Summary
In the OpenAI /v1/responses path, failover or same-request account switching can accidentally forward the original raw request body even after account.model_mapping was applied on an earlier attempt. This can leak alias models such as alias-model to the next upstream account instead of the mapped base model.
What happens
- The handler enters the
/v1/responses failover loop and passes the original raw body to OpenAIGatewayService.Forward.
Forward parses/caches the request body map in the gin context via OpenAIParsedRequestBodyKey.
- Account model mapping mutates the cached map, e.g.
alias-model -> base-model, and serializes the body for that first attempt.
- If the first upstream attempt fails and the handler loops to another account, the handler again passes the original raw
body.
Forward reuses the cached map from the previous attempt. Since the cached map already contains base-model, the mapping block no longer marks bodyModified=true.
- The outgoing request is then built from the original raw body, which still contains
alias-model.
The result is that the next upstream account can receive the unmapped alias model even though the account has a valid model_mapping.
Expected behavior
Every upstream attempt should be built from a body consistent with the current account mapping. A cached parsed body from a previous attempt should not cause the raw original body to be sent unchanged.
Likely affected code
backend/internal/handler/openai_gateway_handler.go: /responses failover loop reuses the raw request body for each attempt.
backend/internal/service/openai_gateway_service.go: getOpenAIRequestBodyMap reuses OpenAIParsedRequestBodyKey; Forward mutates that cached map but only reserializes when bodyModified is set during the current call.
Possible fixes
- Clear the parsed request body cache before each new upstream attempt, or
- make the cache body-specific / immutable, or
- force serialization when
Forward receives a cached parsed map whose model differs from the raw body model.
A regression test should cover one gin context making two Forward calls: the first call maps alias-model -> base-model and fails over, then the second call must still send base-model upstream rather than the original alias-model.
Summary
In the OpenAI
/v1/responsespath, failover or same-request account switching can accidentally forward the original raw request body even afteraccount.model_mappingwas applied on an earlier attempt. This can leak alias models such asalias-modelto the next upstream account instead of the mapped base model.What happens
/v1/responsesfailover loop and passes the original rawbodytoOpenAIGatewayService.Forward.Forwardparses/caches the request body map in the gin context viaOpenAIParsedRequestBodyKey.alias-model -> base-model, and serializes the body for that first attempt.body.Forwardreuses the cached map from the previous attempt. Since the cached map already containsbase-model, the mapping block no longer marksbodyModified=true.alias-model.The result is that the next upstream account can receive the unmapped alias model even though the account has a valid
model_mapping.Expected behavior
Every upstream attempt should be built from a body consistent with the current account mapping. A cached parsed body from a previous attempt should not cause the raw original body to be sent unchanged.
Likely affected code
backend/internal/handler/openai_gateway_handler.go:/responsesfailover loop reuses the raw request body for each attempt.backend/internal/service/openai_gateway_service.go:getOpenAIRequestBodyMapreusesOpenAIParsedRequestBodyKey;Forwardmutates that cached map but only reserializes whenbodyModifiedis set during the current call.Possible fixes
Forwardreceives a cached parsed map whose model differs from the raw body model.A regression test should cover one gin context making two
Forwardcalls: the first call mapsalias-model -> base-modeland fails over, then the second call must still sendbase-modelupstream rather than the originalalias-model.