Summary
GET /publishers and GET /studios return HTTP 200 with a bare error body instead of a JSON:API document:
{"error":"dial tcp 10.107.124.46:6379: connect: connection refused"}
Every other resource endpoint (/systems, /licenses, /volumes, /persons, /contributions, /reviews) works normally against the same Redis config.
Impact
catalog-web's /catalog landing page calls fetchNamed(path:) for /publishers and /studios via catalog-api-client.swift. That client only checks the HTTP status code (200 here) before decoding, so it tries to decode this error body as a JSONAPIDocument and fails with a raw DecodingError, which catalog-web surfaces unhandled as a 400:
{"reason":"No such key 'data' at path ''. No value associated with key CodingKeys(stringValue: \"data\", intValue: nil) (\"data\").","error":true}
This currently makes the entire /catalog page unusable on dev.
What I ruled out
- Not a transient/stale-connection issue: reproduces identically on a freshly restarted
api-v1 pod (deleted and let it recreate, same failure immediately after).
- Not a network reachability issue: from inside the pod,
nc -zv 10.107.124.46 6379 (the exact host:port in the error) succeeds.
- Not a config issue:
REDIS_HOST, REDIS_PORT, REDIS_PASS, and CACHE_TTLS (which includes publishers=2h and studios=2h alongside every other working resource type) all look correct and identical in shape to the working resources.
Given the error message reports the literal ClusterIP (10.107.124.46) rather than the REDIS_HOST DNS name (redis.sweetrpg-catalog.svc.cluster.local) the other endpoints presumably use, the publishers/studios handlers likely construct their own Redis client differently from the rest (a separately cached/resolved connection, a different client instance, or a hardcoded address) rather than sharing whatever code path the working endpoints use. Worth comparing server/publishers.go and server/studios.go against server/systems.go (which works) for how each obtains its Redis client.
Environment
Observed on dev (api-v1 in sweetrpg-catalog), 2026-08-14. Reproducible via:
curl https://dev.sweetrpg.com/api/0/catalog/publishers
curl https://dev.sweetrpg.com/api/0/catalog/studios
Summary
GET /publishersandGET /studiosreturn HTTP 200 with a bare error body instead of a JSON:API document:{"error":"dial tcp 10.107.124.46:6379: connect: connection refused"}Every other resource endpoint (
/systems,/licenses,/volumes,/persons,/contributions,/reviews) works normally against the same Redis config.Impact
catalog-web's/cataloglanding page callsfetchNamed(path:)for/publishersand/studiosviacatalog-api-client.swift. That client only checks the HTTP status code (200 here) before decoding, so it tries to decode this error body as aJSONAPIDocumentand fails with a rawDecodingError, whichcatalog-websurfaces unhandled as a 400:{"reason":"No such key 'data' at path ''. No value associated with key CodingKeys(stringValue: \"data\", intValue: nil) (\"data\").","error":true}This currently makes the entire
/catalogpage unusable on dev.What I ruled out
api-v1pod (deleted and let it recreate, same failure immediately after).nc -zv 10.107.124.46 6379(the exact host:port in the error) succeeds.REDIS_HOST,REDIS_PORT,REDIS_PASS, andCACHE_TTLS(which includespublishers=2handstudios=2halongside every other working resource type) all look correct and identical in shape to the working resources.Given the error message reports the literal ClusterIP (
10.107.124.46) rather than theREDIS_HOSTDNS name (redis.sweetrpg-catalog.svc.cluster.local) the other endpoints presumably use, thepublishers/studioshandlers likely construct their own Redis client differently from the rest (a separately cached/resolved connection, a different client instance, or a hardcoded address) rather than sharing whatever code path the working endpoints use. Worth comparingserver/publishers.goandserver/studios.goagainstserver/systems.go(which works) for how each obtains its Redis client.Environment
Observed on dev (
api-v1insweetrpg-catalog), 2026-08-14. Reproducible via: