diff --git a/extensions/openai/openai-chatgpt-oauth-flow.runtime.test.ts b/extensions/openai/openai-chatgpt-oauth-flow.runtime.test.ts index 05102e8eaaa0..a4bbac1e8186 100644 --- a/extensions/openai/openai-chatgpt-oauth-flow.runtime.test.ts +++ b/extensions/openai/openai-chatgpt-oauth-flow.runtime.test.ts @@ -356,6 +356,30 @@ describe("OpenAI Codex OAuth flow", () => { }); }); + it.each([ + { + operation: "exchange" as const, + run: () => + exchangeOpenAIAuthorizationCode("code", "verifier", resolveOpenAIRedirectUri("localhost")), + }, + { + operation: "refresh" as const, + run: () => refreshOpenAIAccessToken("old-refresh-token"), + }, + ])( + "returns a failed result when the token $operation response is malformed JSON", + async ({ operation, run }) => { + mockTokenResponseText('{"access_token":"access-token","refresh_to'); + + const result = await run(); + + expect(result).toEqual({ + type: "failed", + message: `OpenAI Codex token ${operation} failed: response is not valid JSON`, + }); + }, + ); + it("times out token refresh requests", async () => { ssrfMocks.fetchWithSsrFGuard.mockRejectedValueOnce(timeoutError()); diff --git a/extensions/openai/openai-chatgpt-oauth-token.runtime.ts b/extensions/openai/openai-chatgpt-oauth-token.runtime.ts index 67a46f102381..13247a3c100b 100644 --- a/extensions/openai/openai-chatgpt-oauth-token.runtime.ts +++ b/extensions/openai/openai-chatgpt-oauth-token.runtime.ts @@ -112,7 +112,15 @@ async function readOpenAITokenResponse( message: `OpenAI Codex token ${operation} failed (${response.status}): ${text || response.statusText}`, }; } - const json = (await response.json()) as TokenResponseJson; + let json: TokenResponseJson; + try { + json = (await response.json()) as TokenResponseJson; + } catch { + return { + type: "failed", + message: `OpenAI Codex token ${operation} failed: response is not valid JSON`, + }; + } if (!isRecord(json)) { return { type: "failed",