POST /api/v2/tracks/{id}/canvas-ticket answers 404 for a track that has no canvas, and the client asks again on every mount — a burst of them in the console during an ordinary session.
The 404 itself is handled correctly: canvasUrl (webapp/src/api.ts:647) catches it and returns null, so nothing throws. What the console shows is the request, which the browser logs whatever the JavaScript does with it.
The cause is canvasQuery (webapp/src/queries.ts:231), which carries staleTime: 0 and gcTime: 0. Those two zeros were deliberate in #204 — a canvas ticket expires, so it must never be served from a cache. But they do not separate two answers of opposite nature:
- a ticket, which expires and must not be kept;
- "this track has no canvas", which does not expire within a session.
Expected
Remember the negative answer for the session, and only it. Never keep a live ticket.
How the test can fail for its own reason
Mount the panel twice for a track with no canvas and count the requests: one, not two. A mock that answers instantly will pass either way — see the trap recorded in the plan.
Same family as the favicon loop closed by #205: a stable answer asked again for ever.
Recorded in docs/ui-and-missing-features-plan.md, section 1.
POST /api/v2/tracks/{id}/canvas-ticketanswers404for a track that has no canvas, and the client asks again on every mount — a burst of them in the console during an ordinary session.The 404 itself is handled correctly:
canvasUrl(webapp/src/api.ts:647) catches it and returnsnull, so nothing throws. What the console shows is the request, which the browser logs whatever the JavaScript does with it.The cause is
canvasQuery(webapp/src/queries.ts:231), which carriesstaleTime: 0andgcTime: 0. Those two zeros were deliberate in #204 — a canvas ticket expires, so it must never be served from a cache. But they do not separate two answers of opposite nature:Expected
Remember the negative answer for the session, and only it. Never keep a live ticket.
How the test can fail for its own reason
Mount the panel twice for a track with no canvas and count the requests: one, not two. A mock that answers instantly will pass either way — see the trap recorded in the plan.
Same family as the favicon loop closed by #205: a stable answer asked again for ever.
Recorded in
docs/ui-and-missing-features-plan.md, section 1.