Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/fixes/7521-codex-test-probe-model.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Fixed the Codex connection **Test** button always reporting success for ChatGPT-account tokens: the probe used `gpt-5.3-codex`, a codex-only model ChatGPT accounts reject with a 400 — the same status the probe treats as "auth OK", so a bad token was indistinguishable from a good one. It now probes with `gpt-5.5`, a model ChatGPT-account sessions actually support (#7521).
7 changes: 6 additions & 1 deletion src/app/api/providers/[id]/test/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,12 @@ const OAUTH_TEST_CONFIG = {
"User-Agent": "codex-cli/1.0.18 (macOS; arm64)",
},
// Minimal invalid body — triggers a fast 400 without consuming quota.
body: JSON.stringify({ model: "gpt-5.3-codex", input: [], stream: false, store: false }),
// #7521: probe with a ChatGPT-account-supported model. "gpt-5.3-codex" is a
// codex-only id that ChatGPT accounts reject with a 400 for the WRONG reason
// (unsupported model, not "auth ok, body invalid") — collapsing the auth signal
// so a bad token looks the same as a good one. "gpt-5.5" is served for
// ChatGPT sessions; `input: []` still yields the intended 400.
body: JSON.stringify({ model: "gpt-5.5", input: [], stream: false, store: false }),
// 400 = bad request, but auth was accepted; only 401/403 means the token is bad.
acceptStatuses: [400],
refreshable: true,
Expand Down
14 changes: 14 additions & 0 deletions tests/unit/oauth-connection-test-codex-endpoint.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,20 @@ test("codex test probes the real /responses endpoint and treats 400 as 'auth ok'
const headers = (calls[0].init?.headers ?? {}) as Record<string, string>;
assert.equal(headers.Authorization, "Bearer fake-codex-token");
assert.ok(calls[0].init?.body, "must send a minimal body so the endpoint returns 400 (not 405)");

// #7521: the probe model must be one ChatGPT-account sessions actually support.
// "gpt-5.3-codex" is rejected outright for ChatGPT accounts ("The 'gpt-5.3-codex'
// model is not supported when using Codex with a ChatGPT account."), which also
// returns 400 — masking a bad token behind the same status code as a good one and
// making the Test button always report success. Assert the probe body carries a
// supported model instead.
const parsedBody = JSON.parse(String(calls[0].init?.body));
assert.equal(parsedBody.model, "gpt-5.5", "probe must use a ChatGPT-account-supported model");
assert.notEqual(
parsedBody.model,
"gpt-5.3-codex",
"probe must not use the codex-only model ChatGPT accounts reject (#7521)"
);
});

test("codex test reports invalid when the endpoint returns 401 (port PR#347)", async (t) => {
Expand Down
Loading