Skip to content

fix(sse): set X-OmniRoute-Selected-Connection-Id on successful combo dispatches (#11810) - #11986

Merged
diegosouzapw merged 1 commit into
release/v3.8.51from
fix/11810-combo-success-connection-header
Aug 29, 2026
Merged

diegosouzapw merged 1 commit into
release/v3.8.51from
fix/11810-combo-success-connection-header

Conversation

@diegosouzapw

Copy link
Copy Markdown
Owner

Closes #11810

Root cause

On a successful provider dispatch, handleSingleModelChat()'s result.success branch in src/sse/handlers/chat.ts returned result.response (non-streaming) or wrapResponseWithOAuthSessionRelease(result.response, releaseOAuthSession) (streaming) directly, without first calling withSelectedConnectionHeader() — unlike every failure exit in the same function, which does call it. As a result, X-OmniRoute-Selected-Connection-Id was absent on every successful response for a dynamically-selected (unpinned) connection, so combo.ts's consumers (success-decay, provider cooldown recovery, webhook attribution, session stickiness, LKGP) fell back to the target's static connectionId, which is empty for provider-level combo targets like openai/o3-mini.

Fix

Apply withSelectedConnectionHeader(result.response, credentials?.connectionId) to result.response before both the streaming-wrap and the direct non-streaming return in the result.success block of handleSingleModelChat, mirroring the pattern already used on every failure exit of the same function.

Regression test

tests/unit/combo-success-selected-connection-header-11810.test.ts — two cases (non-streaming and streaming success) that dispatch through the real handleChat → handleComboChat → handleSingleModelChat pipeline with a mocked upstream fetch, and assert the response carries X-OmniRoute-Selected-Connection-Id for a dynamically-selected (unpinned provider-level) connection.

  • RED (pre-fix, both cases): expected the response to carry the dynamically selected connection id (...), got null
  • GREEN (post-fix): tests 2, pass 2, fail 0

Gates run (all green)

  • node --import tsx/esm --test tests/unit/combo-success-selected-connection-header-11810.test.ts — 2/2 pass
  • Sibling regression coverage: tests/unit/combo-selected-connection-success.test.ts, tests/unit/rate-limit-local-error-classification.test.ts, tests/unit/rate-limit-queue-timeout-lockout.test.ts, tests/unit/account-fallback-service.test.ts, tests/unit/stream-early-eof-affinity-8928.test.ts, tests/unit/chat-safetynet-reqid-6097.test.ts — 101/101 pass
  • node scripts/check/check-file-size.mjs — OK
  • node scripts/check/check-complexity.mjs — OK (2672 violations vs baseline 2774)
  • node scripts/check/check-cognitive-complexity.mjs — OK (1192 violations vs baseline 1223)
  • node scripts/check/check-changelog-integrity.mjs — OK
  • npm run typecheck:core — clean
  • npx eslint --suppressions-location config/quality/eslint-suppressions.json src/sse/handlers/chat.ts tests/unit/combo-success-selected-connection-header-11810.test.ts — 0 errors

Note: tests/unit/combo-provider-cooldown.test.ts ("combo failover skips the cooled provider target on the next request") was observed flaking under this run due to extreme devbox CPU contention from many concurrent parallel sessions (test durations of 100-124s for a test whose logic depends on a 3s cooldown window expiring between two sequential requests). This test is structurally unrelated to this fix (it asserts connection-cooldown/retry-count behavior, not response headers), and the diff here only touches the result.success return path — no cooldown/backoff logic. Re-running the other 101 sibling tests touching the same header/function all passed.

⚠️ base-red inherited: #11874 — docs-sync (README provider count), unrelated to this fix.

@diegosouzapw
diegosouzapw merged commit bd04bb9 into release/v3.8.51 Aug 29, 2026
20 checks passed
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
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.

fix(resilience): combo success omits selected connection header

2 participants