Skip to content

Commit b2ea01f

Browse files
fix(openai): always fail on codex Responses-API error events (#87)
Error/failed events without error/message fields were silently ignored, risking continued processing of a broken stream. Throw unconditionally on response.error/error/response.failed (with an Unknown error/failure fallback). Adds a test for the no-details case.
1 parent f9cb644 commit b2ea01f

2 files changed

Lines changed: 27 additions & 11 deletions

File tree

src/api/providers/__tests__/openai-codex-responses.spec.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,5 +515,27 @@ describe("OpenAiHandler - Codex model detection", () => {
515515
}
516516
}).rejects.toThrow("Responses API error: Something went wrong")
517517
})
518+
519+
it("throws on an error event even when it carries no error/message details", async () => {
520+
handler = new OpenAiHandler({
521+
openAiApiKey: "test-key",
522+
openAiModelId: "gpt-5.3-codex",
523+
openAiUseAzure: true,
524+
})
525+
526+
mockResponsesCreate.mockResolvedValue({
527+
[Symbol.asyncIterator]: async function* () {
528+
yield { type: "response.failed" }
529+
},
530+
})
531+
532+
await expect(async () => {
533+
for await (const _chunk of handler.createMessage("System", [{ role: "user", content: "Hello" }], {
534+
taskId: "test",
535+
})) {
536+
// consume
537+
}
538+
}).rejects.toThrow("Response failed: Unknown failure")
539+
})
518540
})
519541
})

src/api/providers/openai.ts

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -836,22 +836,16 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl
836836
continue
837837
}
838838

839-
// Handle error events
839+
// Handle error events. Always fail on an error/failed event type, even
840+
// when it carries no `error`/`message`, so we never keep consuming a
841+
// stream the API has already reported as broken.
840842
if (event?.type === "response.error" || event?.type === "error") {
841-
if (event.error || event.message) {
842-
throw new Error(
843-
`Responses API error: ${event.error?.message || event.message || "Unknown error"}`,
844-
)
845-
}
843+
throw new Error(`Responses API error: ${event.error?.message || event.message || "Unknown error"}`)
846844
}
847845

848846
// Handle failed event
849847
if (event?.type === "response.failed") {
850-
if (event.error || event.message) {
851-
throw new Error(
852-
`Response failed: ${event.error?.message || event.message || "Unknown failure"}`,
853-
)
854-
}
848+
throw new Error(`Response failed: ${event.error?.message || event.message || "Unknown failure"}`)
855849
}
856850

857851
// Fallback for older formats

0 commit comments

Comments
 (0)