Skip to content

v3.5.1 — Hotfix: session-id is a request header

Choose a tag to compare

@vsits-proxy-builder vsits-proxy-builder released this 05 May 19:35
· 100 commits to main since this release
9f3d85d

Hotfix for v3.5.0. Session-id headers (x-claude-code-session-id and the legacy fallbacks) live on the request, not the response. The v3.5.0 implementation read them from ctx.headers in onResponseStart — but that ctx carries response headers, and Anthropic doesn't echo session-id back. Net effect on multi-agent hosts running v3.5.0: every per-session file landed at ~/.claude/quota-status/sessions/unknown.json with session_id: null, defeating the whole point of the per-session split.

If you upgraded to v3.5.0, please upgrade to v3.5.1.

What changed

proxy/extensions/cache-telemetry.mjs gains an onRequest hook that captures session-id from request headers and stashes it on ctx.meta._sessionId. onStreamEvent reads from meta as before. The proxy server passes the same meta object through onRequest → onResponseStart → onStreamEvent, so the threading works end-to-end without further refactoring.

The directive design (the per-session-files architecture, the canonical filename rule, the sessions/ subdirectory layout) is correct as shipped in v3.5.0. The bug was purely that the implementation read from the wrong ctx.

Production timeline

  • 2026-05-05 19:21 UTC — v3.5.0 deployed on visits-01.
  • First request after restart landed at sessions/unknown.json with session_id: null despite being a real CC turn (717-byte cache_creation, 99.8% hit rate).
  • Subsequent requests over the next ~3 minutes also landed at unknown.json. Bug confirmed in production.
  • v3.5.1 hotfix shipped within an hour.

Regression coverage

Two new tests in test/proxy-cache-telemetry.test.mjs:

  • 0a: drives request and response headers SEPARATELY (only request carries session-id); asserts the per-session file is named after the request id, not unknown. This test would fail against v3.5.0's broken code, locking in the fix.
  • 0b: sanity check that absence-on-request still falls through to unknown.json per the canonical filename rule.

Upgrade

npm install -g claude-code-cache-fix@3.5.1

After restart, expect:

  • ~/.claude/quota-status/account.json continues being written every response.
  • The previously-overgrown sessions/unknown.json will stop receiving new writes from real CC traffic.
  • Per-session files will start landing at ~/.claude/quota-status/sessions/<actual-uuid>.json based on each session's x-claude-code-session-id header.
  • Existing sessions/unknown.json from the v3.5.0 window remains on disk and will be swept naturally after CACHE_FIX_QUOTA_STATUS_TTL_DAYS (default 7).

Tests

733 → 735 (+2): regression coverage for the request-vs-response ctx split.

Architecture

  • PR: #107
  • Bug surfaced by: AI Team Lead and Chris (operator), spotting the unknown.json pattern in production immediately post-deploy.