Skip to content

fix(combo): strip content-encoding on re-serialized child requests#230

Merged
Ingwannu merged 1 commit into
lidge-jun:devfrom
jonathanli12:fix/combo-child-strip-content-encoding
Jul 22, 2026
Merged

fix(combo): strip content-encoding on re-serialized child requests#230
Ingwannu merged 1 commit into
lidge-jun:devfrom
jonathanli12:fix/combo-child-strip-content-encoding

Conversation

@jonathanli12

Copy link
Copy Markdown
Contributor

Summary

  • Combo failover re-serializes an already-decoded request body as plain JSON for each target, but it only stripped content-length and left the parent's Content-Encoding header in place.
  • When Codex sends content-encoding: zstd, the combo child path then tries to zstd-decompress uncompressed JSON. That fails as Unknown frame descriptor, gets mapped to Invalid JSON body, and combo failover stops before later targets run.
  • Observed with combo/xai_grok_fallback: first attempt (xai/grok-4.5) failed in ~1ms with sendCount: 0, and Cursor never got a turn even though direct cursor/grok-4.5 worked.

Fix

  • In handleComboResponses, also delete content-encoding when building the child Request.
  • Add a focused regression that proves the buggy header rewrite fails and the fixed rewrite succeeds.

Test plan

  • bun test --isolate tests/request-decompress.test.ts tests/combo-child-headers.test.ts tests/combos.test.ts
  • bun x tsc --noEmit
  • Manual repro against a live proxy: zstd-encoded POST /v1/responses with model=combo/xai_grok_fallback returned 200 and COMBO_OK after the local patch
  • CI green on this PR

Notes

  • Upstream main / v2.7.31 still has the bug.
  • This is independent of provider auth; the 400 happens locally while decoding the combo child request body.

Combo failover clones the already-decoded request body as plain JSON but
kept the parent Content-Encoding header. When Codex sends zstd-compressed
bodies, the child path then tries to decompress uncompressed JSON, which
surfaces as "Unknown frame descriptor" / Invalid JSON body and stops
failover before later targets run.

Drop content-encoding alongside content-length when building the child
Request, and add a focused regression for that header rewrite.
@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown

Target branch corrected

This pull request now targets dev.

The [WRONG BRANCH] title prefix has been removed. The pull request has been marked ready for review again.

@github-actions github-actions Bot changed the title fix(combo): strip content-encoding on re-serialized child requests [WRONG BRANCH] fix(combo): strip content-encoding on re-serialized child requests Jul 21, 2026
@github-actions
github-actions Bot marked this pull request as draft July 21, 2026 22:36
@jonathanli12
jonathanli12 changed the base branch from main to dev July 21, 2026 22:36
@jonathanli12
jonathanli12 marked this pull request as ready for review July 21, 2026 22:36
@github-actions github-actions Bot changed the title [WRONG BRANCH] fix(combo): strip content-encoding on re-serialized child requests fix(combo): strip content-encoding on re-serialized child requests Jul 21, 2026
@lidge-jun

Copy link
Copy Markdown
Owner

Thanks for the fix — the header logic itself is right: once the child body is re-serialized from decoded JSON, content-encoding must be dropped along with content-length.

One review note before this can be absorbed: the added test re-implements the header-cloning logic inside the test instead of exercising the real handleComboResponses path, so it would keep passing even if the deletion were removed from the production code. Could you rework it to drive the actual combo child request path (or at least call the shared helper the server uses)? I've approved the CI runs so the full cross-platform suite can run in the meantime.

Copy link
Copy Markdown
Owner

Reviewed the combo request path and security impact. Removing content-encoding is the correct fix because the child body has already been decoded and re-serialized. No malicious behavior or credential risk found. The Windows failure is an unrelated CLI timeout; I am merging this and will strengthen the regression coverage on dev so it exercises the production helper rather than duplicating the header rewrite in the test.

@Ingwannu
Ingwannu merged commit afce7cf into lidge-jun:dev Jul 22, 2026
9 of 11 checks passed
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.

3 participants