The Steam client/PICS plane cannot open its websocket, and get_account_licenses hangs unbounded instead of failing #21
Labels
No labels
autonomy
async-consult
autonomy
epic
autonomy
headless
autonomy
live-collab
c#
priority
P0
priority
P1
priority
P2
priority
P3
priority
P4
role/ai
role/creator
role/design
role/director
role/engineer
role/exec
role/human
role/ops
role/qa
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
coilyco-gaming/steam-ops#21
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Filed by Olaf (ops seat,
claude) from a live status check of the deployedsteam-mcp, 2026-08-19 ~22:41-22:49 UTC.What is healthy
Everything except the client/PICS plane. Pod
steam-mcp-ff94577f-2mxkvon kai-server, imageforgejo.coilysiren.me/coilyco-gaming/steam-mcp:3a0cacf26c3c4d7bc70c5da3c7f51c2debf52183, up 2d1h, 0 restarts.steam-mcp-metaandsteam-mcp-oauth2-proxyboth Ready. The gated public path answers correctly:/.well-known/oauth-protected-resourcereturns 200 unauthenticated and/mcpreturns 401 without a Bearer JWT. The tailnet NodePorthttp://kai-server:30112/mcpserves.Two planes verified live through the MCP:
get_recently_playedreturned 6 normalized records.get_store_search_results(query="Eco")returned 10 items with appids and prices. This is the surface coilyco-gaming/sirens-echo#902 reported as returning 0 for every query on 2026-08-17. It works now on the currently deployed image, so #902 looks resolved and wants a close with this as the evidence.The defect
get_account_licenses(the authenticated client/PICS plane) never returns. I let it run past 8 minutes with no result and no error before stopping it. There is no timeout: the call hangs rather than failing.Pod stderr at the moment of the call:
The websocket dies about one second after the attempt, and the underlying client reports it cannot reconnect. The tool call above it never learns that and waits forever.
What the log volume establishes
Aggregated over the pod's entire 2-day life,
k8s.deployment.name = 'steam-mcp':body CONTAINS 'websocket'- 3 rows total, all inside the hour of my call.body CONTAINS 'Websocket closed'- 2 rows total, same hour.So the client session is established lazily on first use, and nobody had exercised this plane in the pod's whole lifetime until now. This is not a regression that started today; it is a plane that has been silently unexercised and is broken on first touch. The web_api and storefront planes carry all observed traffic, which is why nothing surfaced it.
Two separate problems, and the second is the worse one
The session will not establish. Most likely
/steam/client-refresh-tokenis expired or invalid.deploy/main.yml:140maps it toSTEAM_CLIENT_REFRESH_TOKEN; the source reads it and is supposed to persist a rotated token back to the same SSM param. I have not read the token and am not going to. Whether it is expired, whether the rotation write-back is landing, and whether the reconnect gives up too early are all things the source repo can settle and I cannot from outside.A dead credential presents as a hang, not an error. This is the part that outlives the specific token. A caller gets no result, no exception, and no signal to fall back on. An agent harness with a tool timeout burns its budget; one without it wedges. A failed authenticated read must return an error naming the plane and the cause, and it must do so in seconds. This is the same shape as steam-ops#18's fourth invariant - an unreadable dataset reports null, never zero - extended one step: an unreachable plane reports an error, never silence.
Acceptance
get_account_licenseseither returns licenses or fails with a named error, in bounded time, on a dead or missing client credential.get_pics_product_infoincluded, since it shares the session.Not in scope here
The web_api and storefront planes are fine and need no change. Nothing about the Authelia gate or the NodePort is implicated.
Duplicate of #13, which I found after filing this. #13 has the same root cause, is three weeks older, and already carries the right label and priority.
Evidence folded into #13 as a comment, including the one genuinely new finding: the bounded sanitized error #13 records at ~50 seconds no longer fires, and the call now hangs unbounded instead.
Closing here. Work the problem on #13.