Skip to content

🤖 fix: tokenizer cache key (CRC32 + length) collides, making token totals inexact and timing-dependent #4654

Description

@ThomasK33

Found while fixing #4643 (PR #4647).

Problem

buildCacheKey in src/node/utils/main/tokenizer.ts keys the token-count LRU and in-flight map by model:CRC32(text):text.length. Distinct texts of the same length collide: the remote UAT found 17 colliding texts in a 1.24M-row synthetic chat. A colliding text reuses another text's count.

Before #4647 every submission happened in one synchronous turn, so the same history always produced the same (slightly wrong) total. With the calculation now interleaving, which text claims a shared key first depends on timing, so totals differ slightly between runs and between concurrent calculations (UAT: 962 vs 946 vs 972 on a small scale; locally 68,099,845 vs 68,099,879 of 68M). The error is ~1e-7, but the persisted cache can store either value.

Fix direction

Use a collision-resistant key (e.g. a 64-bit/128-bit hash, or the text itself for short strings) and keep the LRU memory bounded.


Generated with xum • Model: anthropic:claude-opus-5-5 • Thinking: high • Cost: $9.90

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions