fix(llm): surface llm-connect's error body instead of a bare 502
llm-connect maps every provider API error onto HTTP 502 and puts the real cause in the body (llm_connect/server.py::_error_response: error, provider_status). LLMConnectClient.complete called raise_for_status() and threw that body away, so a revoked OpenRouter key was indistinguishable from a downed gateway — four days of production evidence read as "llm-connect is down". Live check confirms one fault, not two: the llm-connect pod is Running 1/1 with healthy endpoints, and today's FI/Binky/triage runs still 502 after yesterday's rollout, matching the sanitized upstream 401 railiance-platform reported. The client now raises with error, provider_status, provider, model and a bounded copy of llm-connect's already-sanitized message, under a field allowlist so no provider blob or key material reaches the run artefact. Refs ACTIVITY-WP-0031-T01, T03. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
0d9ddbaa08
commit
459a272974
4 changed files with 169 additions and 5 deletions
|
|
@ -8,7 +8,7 @@ status: active
|
|||
owner: codex
|
||||
topic_slug: activity-core
|
||||
created: "2026-08-20"
|
||||
updated: "2026-08-20"
|
||||
updated: "2026-08-21"
|
||||
related:
|
||||
- ACTIVITY-WP-0021
|
||||
- ACTIVITY-WP-0022
|
||||
|
|
@ -49,6 +49,32 @@ still returns sanitized OpenRouter HTTP 401, proving the canonical key itself
|
|||
is rejected. T01 remains `wait` on an attended OpenRouter account owner to mint
|
||||
and safely provision a replacement key; no key value was read or printed.
|
||||
|
||||
Progress 2026-08-21 (activity-core half, no custody boundary crossed): live
|
||||
evidence confirms a single fault, not two. FI, Binky, and daily triage still
|
||||
fail today (`05:20` / `05:30` / `06:23` UTC) with `502 Bad Gateway` from
|
||||
llm-connect — **after** yesterday's rollout (`llm-connect` pod is `Running`
|
||||
1/1, endpoints healthy). That 502 is not a dead gateway:
|
||||
`llm_connect/server.py::_error_response` maps **every** `LLMAPIError` onto 502
|
||||
and carries the real cause in the body (`error`, `provider_status`). So the
|
||||
502s and the reported upstream 401 are the same rejected key.
|
||||
|
||||
`LLMConnectClient.complete` called `raise_for_status()` and discarded that
|
||||
body, so four days of production evidence read as "llm-connect is down" when it
|
||||
meant "the provider rejected the key". Fixed: the client now raises with
|
||||
`error`, `provider_status`, `provider`, `model`, and a bounded copy of
|
||||
llm-connect's already-sanitized `message`, under a field allowlist so no
|
||||
provider blob or key material can reach the run artefact. Five tests cover the
|
||||
401-behind-502 case, the allowlist, bounding, and unusable bodies.
|
||||
|
||||
The identical body-discarding call exists in
|
||||
`rein-aharness/rein_aharness/llm_connect_client.py:65`, which is what produces
|
||||
the opaque ops_run failure text in the status table. Not ours to edit —
|
||||
handed to rein-aharness.
|
||||
|
||||
T01 still `wait`: the key rotation itself remains attended and
|
||||
railiance-platform-owned. What changed is that the next failure will name its
|
||||
own cause.
|
||||
|
||||
## Emergency-pause weekly SBOM fan-out
|
||||
|
||||
```task
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue