Skip to content

fix: the fifth leaking branch, and a claim that outran its code again - #216

Merged
fstubner merged 1 commit into
mainfrom
fix/midstream-key-leak
Sep 3, 2026
Merged

fix: the fifth leaking branch, and a claim that outran its code again#216
fstubner merged 1 commit into
mainfrom
fix/midstream-key-leak

Conversation

@fstubner

@fstubner fstubner commented Sep 3, 2026

Copy link
Copy Markdown
Owner

A verification pass on #215 returned NOT CONFIRMED.

#215 asserted that "every branch that returns endpoint-authored text now goes through one #safe()". A fifth branch did not:

error: streamError ?? this.#safe(describeUnusableBody(rawSeen))

The scrub sat on the fallback. streamError holds the endpoint's own message, parsed straight out of an SSE error event by both wire-protocol parsers, and it reached DispatchResult.error — and logs/dispatches.jsonl — verbatim.

It is also the likeliest shape of the lot: a 200 with text/event-stream carrying an error object is how OpenAI-compatible gateways and Anthropic both report an auth failure once the stream is open, and jobs only ever stream. Reproduced against the built artifact with a URL-embedded key and one echoed from the Authorization header.

The claim, not just the code

This is the second commit message about this file to describe a wider fix than the code delivered. The #safe docblock no longer asserts completeness — it enumerates the branches that assign DispatchResult.error and says which are ours and which are scrubbed. An enumeration can be checked against the file; a claim of completeness cannot.

Also fixed: describeFetchFailure has always scrubbed the base URL but was never given the api key — the last unscrubbed-for-key site in the file.

Sabotage

Reverted Fails
#safe moved back onto the fallback exactly the 2 mid-stream tests
the key argument to describeFetchFailure exactly the fetch-failure test

Verified at the artifact

All seven error branches driven against built dist/ with a stubbed fetch, no network:

ok   mid-stream sse error (openai)      ok   unusable 200 body (buffered)
ok   mid-stream sse error (anthropic)   ok   http 400 (buffered)
ok   unusable 200 body (stream)         ok   http 400 (stream)
ok   fetch failure

npm run check: 1226 passed, 8 skipped, exit 0.

A verification pass on #215 returned NOT CONFIRMED. That commit asserted
"every branch that returns endpoint-authored text now goes through one
#safe()". A fifth branch did not:

    error: streamError ?? this.#safe(describeUnusableBody(rawSeen))

The scrub sat on the FALLBACK. `streamError` holds the endpoint's own
message, parsed straight out of an SSE `error` event by both wire-protocol
parsers, and it reached DispatchResult.error — and logs/dispatches.jsonl —
verbatim. It is also the likeliest shape of all of them: a 200 with
text/event-stream carrying an error object is how OpenAI-compatible
gateways and Anthropic both report an auth failure once the stream is
open, and jobs only ever stream. Reproduced against the built artifact
with both a URL-embedded key and one echoed from the Authorization header.

That is the second time a commit message about this file claimed a wider
fix than the code delivered, so the #safe docblock no longer asserts
completeness — it enumerates the branches, and the enumeration is checked.

Also: describeFetchFailure has always scrubbed the base URL but was never
given the api key, leaving the last unscrubbed-for-key site in the file.

Sabotage, each separately: moving #safe back onto the fallback fails
exactly the two mid-stream tests; dropping the key argument fails exactly
the fetch-failure test.

Verified at the built artifact, not the diff — all seven error branches
driven with a stubbed fetch, no leak on any. npm run check: 1226 passed,
8 skipped, exit 0.
@fstubner
fstubner merged commit 86ea82b into main Sep 3, 2026
4 checks passed
@fstubner
fstubner deleted the fix/midstream-key-leak branch September 3, 2026 21:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant