Skip to content

fix(api): mark unclaimed_id and block_confirmation responses no-store - #1064

Merged
rickyrombo merged 1 commit into
mainfrom
fix/unclaimed-id-no-store
Oct 27, 2026
Merged

rickyrombo merged 1 commit into
mainfrom
fix/unclaimed-id-no-store

Conversation

@rickyrombo

Copy link
Copy Markdown
Contributor

What

/v1/{users,tracks,playlists,comments,events}/unclaimed_id (and the unclaimed-id aliases) and /block_confirmation now respond with Cache-Control: no-store.

Why

An edge cache in front of /v1/* was storing unclaimed_id responses keyed on the full URL. Two requests for the same URL within the cache window got the same id, the second as a cache HIT.

  • Track id collisions. The web and mobile apps fetch one id per track in parallel during an upload, and the SDK's cache-buster (noCache=Math.random()*1000) has only 1000 values. In a large album two tracks often end up with the same id. The chain accepts the first create and the indexer rejects the second as "track already exists", so that track is lost while the client still shows it as published. This was observed on mainnet in uploads of 30+ tracks.
  • Stale confirmation. Clients poll /block_confirmation until their block is indexed. A cached "not yet" can push confirmation past the client's timeout, which triggers retries.

Edge caches that respect origin headers will no longer store these responses, whatever cache rules exist in front of the API. This complements disabling the cache rule; it doesn't replace fixing the SDK's cache-buster or confirming that the entity exists after a write.

Tests

TestUnclaimedIdAndBlockConfirmationAreNotCacheable checks all ten routes. It fails on main for every route and passes with this change. TestBlockConfirmation and the events unclaimed_id tests still pass.

🤖 Generated with Claude Code

An edge cache in front of /v1/*/unclaimed_id returned the same id to
concurrent callers. Clients that fetch an id per track in parallel (bulk
album uploads) then sent two creates with one id, and every create after
the first was rejected as a duplicate. The SDK's cache-buster query param
has only 1000 values, so it does not prevent this.

/block_confirmation is polled until a write's block is indexed; a cached
"not yet" delays confirmation past the client's timeout.

Both now send Cache-Control: no-store, which edge caches honor when they
respect origin headers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@rickyrombo
rickyrombo merged commit c9b6dfe into main Oct 27, 2026
2 checks passed
@rickyrombo
rickyrombo deleted the fix/unclaimed-id-no-store branch October 27, 2026 21:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant