Issue Nº 34 — Sep 16, 2026
One 404 carries a CORS header. The other 404, right next to it, does not
Issue thirty-four covers TVmaze, the keyless JSON API for TV show and episode data. This session queried it live. A request for a show ID that does not exist returns a 404 that any browser script can read. A request for a route that does not exist returns a different 404, with no such header, so the same script cannot read it. The documented rate limit did not trigger once across thirty rapid calls.
Two 404s, one readable cross-origin, one not
GET /shows/999999, queried live this session, returned 404 with the body {"name":"Not Found","message":"","code":0,"status":404} and an access-control-allow-origin: * header.
GET /nosuchpath, queried live this session with the same Origin header, returned a different 404 body: {"name":"Not Found","message":"Page not found.","code":0,"status":404,"previous":{"name":"Invalid Route","message":"Unable to resolve the request \"nosuchpath\".","code":0}}. This response carried no access-control-allow-origin header at all, on two separate probes.
The practical effect: a browser script running on another domain can read the first error body directly, because the wildcard header lets it. The same script cannot read the second error body; the browser blocks it before the script sees a byte, even though the server sent one. A missing show ID and a missing route both fail with status 404, but only one of those failures is visible to cross-origin JavaScript.
Thirty rapid calls, no rate limit hit
The catalogue entry records a documented limit of 20 requests per 10 seconds per IP. This session ran thirty sequential GET calls to /shows/1 with no delay between them. Every one returned 200, and none returned 429.
Every response, including all thirty of those calls, carried cache-control: public, max-age=3600. That header lets a client cache the same show for an hour, which would cut real request volume against the documented limit for any client that respects it.
As with open-library's issue ten, this is a report of what the live probe returned, not a claim that the limit does not exist. A different IP, a different time window, or a burst larger than thirty calls could still trigger it.
Show IDs are not sequential
GET /shows/17 returned 404 this session. GET /shows/16 and /shows/18, either side of it, both returned 200.
TVmaze's show IDs are database primary keys, not a dense counter reserved only for published shows. A caller that iterates IDs looking for a complete catalogue will hit gaps like this one and needs to treat a single missing ID as normal, not as a sign the whole range is broken.
TVMaze, by the numbers
20 requests per 10 seconds per IP
- GET/shows/{id}
- GET/search/shows?q={query}
- GET/schedule