Skip to content

fix(codex-transform): preserve underscore when rewriting call_* tool-call ids#2499

Merged
Wei-Shaw merged 1 commit into
Wei-Shaw:mainfrom
yetone:fix/codex-transform-fc-underscore
May 19, 2026
Merged

fix(codex-transform): preserve underscore when rewriting call_* tool-call ids#2499
Wei-Shaw merged 1 commit into
Wei-Shaw:mainfrom
yetone:fix/codex-transform-fc-underscore

Conversation

@yetone

@yetone yetone commented May 15, 2026

Copy link
Copy Markdown
Contributor

Summary

fixCallIDPrefix in openai_codex_transform.go rewrites
call_<nanoid>fc<nanoid> (missing underscore). The codex backend
then rejects the malformed id with 400 Invalid 'input[N].id' and
sub2api surfaces it as 502 Bad Gateway to the client.

// before (line 1032-1034)
if strings.HasPrefix(id, "call_") {
    return "fc" + strings.TrimPrefix(id, "call_")  // ← missing "_"
}
return "fc_" + id  // ← other branch has it

Repro

Client uses the OpenAI SDK against an OAuth/codex-mode sub2api account.
The model emits a function_call with the standard call_<nanoid> id;
the client replays it on the next hop as an item_reference whose id
mirrors the call_id. fixCallIDPrefix then produces e.g.
fcYYen1qxDejd2myJwcTCf7Nyp (instead of fc_YYen1qxDejd2myJwcTCf7Nyp),
which the upstream codex /responses endpoint rejects:

400 Invalid 'input[N].id': 'fcYYen1qxDejd2myJwcTCf7Nyp'.
    Expected an ID that contains letters, numbers, underscores, or
    dashes, but this value contained additional characters.

Sub2api wraps that into 502 upstream request failed.

Fix

One character — add the missing underscore on the call_ branch so it
matches the fallback branch directly below it.

if strings.HasPrefix(id, "call_") {
    return "fc_" + strings.TrimPrefix(id, "call_")  // ← now matches fallback
}
return "fc_" + id

Impact

  • Affects platform=openai type=oauth accounts whose clients use
    the official OpenAI SDK / Responses-API id conventions
    (call_<nanoid> prefix). Every multi-hop turn after the first tool
    call surfaces as 502 from sub2api.
  • Does not affect API-key accounts (they don't go through
    applyCodexOAuthTransform) or clients that already emit fc_ ids
    directly.

Test plan

  • Codex OAuth account, OpenAI SDK client, multi-hop turn with
    function calls — previously 502 on hop 2+, expected 200 with fix.
  • Confirm no regression for clients sending non-call_-prefixed
    ids (the fallback branch still handles them with fc_ prefix).

…call ids

`fixCallIDPrefix` builds malformed ids when the input has the standard
OpenAI `call_<nanoid>` prefix:

  input:  call_YYen1qxDejd2myJwcTCf7Nyp
  output: fcYYen1qxDejd2myJwcTCf7Nyp   ← no underscore between 'fc' and the nanoid

ChatGPT's codex backend then rejects the replayed item with:

  400 Invalid 'input[N].id': 'fcYYen1qxDejd2myJwcTCf7Nyp'.
       Expected an ID that contains letters, numbers, underscores, or
       dashes, but this value contained additional characters.

Sub2api wraps that into 502 to the client. Clients using the OpenAI SDK
on the OAuth/codex path see every multi-hop turn (after the first tool
call) fail because the item_reference rewritten this way gets sent on
every subsequent hop.

The other two branches of the same function correctly emit `fc_`
(line 1029: pass-through when already `fc*`; line 1035 fallback:
`fc_" + id`). Only the `call_` → `fc_` rewrite was missing the
underscore — looks like a copy-paste slip during the original commit.

Fix: change `"fc"` to `"fc_"` on the call_ branch. One character.

Repro:
  client (OpenAI SDK) sends a function_call_output whose call_id is
  `call_<nanoid>` (default OpenAI format). The sub2api request body
  also contains an item_reference whose id mirrors the call_id (also
  `call_<nanoid>`). On the codex OAuth path, this rewrite fires for
  the item_reference's id, producing the malformed value.

Affects: `platform=openai type=oauth` accounts whose clients use the
official OpenAI SDK / Responses API conventions (id prefix `call_`).
API-key accounts and bridge-mode requests are untouched.
@github-actions

github-actions Bot commented May 15, 2026

Copy link
Copy Markdown
Contributor

All contributors have signed the CLA. ✅
Posted by the CLA Assistant Lite bot.

yetone added a commit to yetone/sub2api that referenced this pull request May 15, 2026
pnpm 10+ promotes the 'Ignored build scripts' warning into an error
when the consumer hasn't approved scripts via package.json's
onlyBuiltDependencies. The frontend lockfile pulls esbuild@0.21.5 and
vue-demi@0.14.10, both of which need postinstall to materialize their
binaries, so a fresh `pnpm install` on v10/v11 dies with:

  [ERR_PNPM_IGNORED_BUILDS] Ignored build scripts: esbuild@0.21.5,
                            vue-demi@0.14.10
  exit code: 1

`pnpm@latest` resolves to whatever is current at build time, so the
Dockerfile builds non-deterministically — it works on v9 (the version
in use when the lockfile was first committed) and fails on v10+. Pin
to v9 so the image keeps building until upstream adopts approve-builds
or pre-declares onlyBuiltDependencies.

NOT a fix to the codex-transform bug — this is purely a build-side
deterministic-Dockerfile change. The fc-underscore PR (Wei-Shaw#2499) is the
real fix and lives on the upstream-bound branch.
@yetone

yetone commented May 15, 2026

Copy link
Copy Markdown
Contributor Author

I have read the CLA Document and I hereby sign the CLA

@yetone

yetone commented May 15, 2026

Copy link
Copy Markdown
Contributor Author

recheck

@Wei-Shaw Wei-Shaw merged commit 11870cf into Wei-Shaw:main May 19, 2026
7 of 9 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators May 19, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants