diff --git a/server/src/services/native-runtime/native-provider-failure.test.ts b/server/src/services/native-runtime/native-provider-failure.test.ts index fb007f906f4..a777eef55d7 100644 --- a/server/src/services/native-runtime/native-provider-failure.test.ts +++ b/server/src/services/native-runtime/native-provider-failure.test.ts @@ -68,6 +68,8 @@ describe("native provider failure observation", () => { [real.replace(model, "other-model"), undefined, false], [real, { httpConnectionFailed: { httpStatusCode: 500 } }, false], [real, "other", false], + // Codex reports its retried 404s with this kind and willRetry; they never end the turn. + [real, { responseStreamDisconnected: { httpStatusCode: 404 } }, false], [real, undefined, true], ] as const) { const other = observation(); diff --git a/server/src/services/native-runtime/native-provider-failure.ts b/server/src/services/native-runtime/native-provider-failure.ts index c139b6c2bda..1d4b4824ed8 100644 --- a/server/src/services/native-runtime/native-provider-failure.ts +++ b/server/src/services/native-runtime/native-provider-failure.ts @@ -266,8 +266,8 @@ export function createNativeProviderFailureObservation(provider: { kind: string; // terminal text (codex 0.160.0). Bind it to the configured model; store neither name nor text. const info = record(failure.codexErrorInfo); const infoKinds = Object.keys(info); - if (infoKinds.length === 1 && ["httpConnectionFailed", "responseStreamDisconnected"].includes(infoKinds[0]!) && - record(info[infoKinds[0]!]).httpStatusCode === 404 && + // Its retried 404s arrive as responseStreamDisconnected with willRetry; only the terminal kind counts. + if (infoKinds.length === 1 && infoKinds[0] === "httpConnectionFailed" && record(info.httpConnectionFailed).httpStatusCode === 404 && failure.message.startsWith(`unexpected status 404 Not Found: The model \`${provider.model}\` does not exist or you do not have access to it.`)) { missingModelTurnId = event.turnId; return;