Skip to content

Commit 8ce9dcf

Browse files
committed
test(inference): prove Codex 404 masks expired credentials as fatal
1 parent 2c38c6f commit 8ce9dcf

2 files changed

Lines changed: 61 additions & 0 deletions

File tree

‎src/inference-error-message.test.ts‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,27 @@ describe("terminalProviderFailureMessage", () => {
160160
);
161161
});
162162

163+
test("terminal Codex credential 404 names the profile with a re-login hint", () => {
164+
const normalized = normalizeInferenceErrorForTerminal(
165+
{ category: "fatal", message: "Not Found", statusCode: 404 },
166+
"codex/work",
167+
);
168+
const message = terminalProviderFailureMessage("codex/work", normalized);
169+
expect(message).toContain('Codex profile "work"');
170+
expect(message.toLowerCase()).toMatch(/log in again/);
171+
expect(message).not.toContain("/model");
172+
});
173+
174+
test("terminal genuine unknown-model 404 keeps switch-models guidance", () => {
175+
const message = terminalProviderFailureMessage("codex/work", {
176+
category: "fatal",
177+
message: "The model 'gpt-99' does not exist",
178+
statusCode: 404,
179+
providerId: "codex/work",
180+
});
181+
expect(message).toContain('"/model"');
182+
});
183+
163184
test.each([
164185
{
165186
name: "Bearer header",

‎src/inference-gateway-error.test.ts‎

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,46 @@ describe("normalizeInferenceErrorForRetry", () => {
279279
expect(normalized).toBe(error);
280280
});
281281

282+
test("Codex 404 without a model marker reclassifies as credential_failure", () => {
283+
const normalized = normalizeInferenceErrorForRetry({
284+
category: "fatal",
285+
message: "Not Found",
286+
statusCode: 404,
287+
providerId: "codex/work",
288+
});
289+
expect(normalized.category).toBe("credential_failure");
290+
expect(normalized.message).toBe(
291+
'Codex profile "work" is not authorized. Log in again.',
292+
);
293+
});
294+
295+
test("Codex 404 naming an unknown model keeps fatal switch-models guidance", () => {
296+
const error = {
297+
category: "fatal" as const,
298+
message: "The model 'gpt-99' does not exist",
299+
statusCode: 404,
300+
providerId: "codex/work",
301+
raw: {
302+
error: {
303+
code: "model_not_found",
304+
message: "The model 'gpt-99' does not exist",
305+
type: "invalid_request_error",
306+
},
307+
},
308+
};
309+
expect(normalizeInferenceErrorForRetry(error)).toBe(error);
310+
});
311+
312+
test("non-Codex 404 keeps fatal switch-models guidance", () => {
313+
const error = {
314+
category: "fatal" as const,
315+
message: "Not Found",
316+
statusCode: 404,
317+
providerId: "custom-provider",
318+
};
319+
expect(normalizeInferenceErrorForRetry(error)).toBe(error);
320+
});
321+
282322
test("known-xAI message-only capacity protocol error becomes retryable", () => {
283323
const normalized = normalizeInferenceErrorForRetry({
284324
category: "protocol_mismatch",

0 commit comments

Comments
 (0)