Skip to content

fix(design/variants): surface real 240s timeout in AbortError message#1774

Open
Pablosinyores wants to merge 1 commit into
garrytan:mainfrom
Pablosinyores:fix/design-variants-timeout-msg
Open

fix(design/variants): surface real 240s timeout in AbortError message#1774
Pablosinyores wants to merge 1 commit into
garrytan:mainfrom
Pablosinyores:fix/design-variants-timeout-msg

Conversation

@Pablosinyores
Copy link
Copy Markdown

Summary

generateVariant in design/src/variants.ts arms its abort timer at 240_000 ms:

const timeout = setTimeout(() => controller.abort(), 240_000);

but the AbortError branch returns "Timeout (120s)" — half the actual bound:

} catch (err: any) {
  clearTimeout(timeout);
  if (err.name === "AbortError") {
    return { path: outputPath, success: false, error: "Timeout (120s)" };
  }

A user staring at Timeout (120s) has no way to know whether to bump the orchestrator timeout, retry, or drop the call — the surfaced number is off by 2x from the timer that fired. This is purely a stale string literal, but it's the only signal a caller gets when the OpenAI Responses API stalls.

No linked issue — caught while auditing design/src/ after #1773 (the gpt-image-2 regression).

Fix

One-line literal correction in variants.ts:128: "Timeout (120s)" -> "Timeout (240s)".

Regression test

Adds a test to the existing design/test/variants-retry-after.test.ts that:

  1. Stubs fetch to return a permanently-pending promise wired to the AbortSignal.
  2. Monkey-patches setTimeout to fast-forward ONLY the 240_000 ms abort timer (delegating all other delays — including the retry-loop exponential backoff — to the real setTimeout so other behaviors aren't affected).
  3. Awaits the resulting AbortError branch and asserts result.error === "Timeout (240s)".

Without the fix this test fails with the pre-fix "Timeout (120s)" literal.

Validation

$ bun test design/test/variants-retry-after.test.ts
 6 pass
 0 fail
 21 expect() calls
Ran 6 tests across 1 file. [8.05s]

(The existing 5 retry-after tests still pass; the new 6th test is the regression pin for the AbortError branch.)

AI assistance disclosure

Patch was drafted with AI assistance. Diff hand-reviewed against variants.ts:61 (the abort timer) and variants.ts:128 (the error branch); test exercises the actual AbortError code path rather than asserting the literal directly so a future timeout change keeps the message and the timer in lockstep.

`generateVariant` in `design/src/variants.ts` arms its abort timer
at 240_000 ms (`setTimeout(() => controller.abort(), 240_000)` at
line 61), but the AbortError branch at line 128 returns
`"Timeout (120s)"` — half the actual bound.

The mismatch is purely a stale string literal, but it's the only
signal a caller gets when the API stalls. A user staring at
`Timeout (120s)` has no way to know whether to bump the orchestrator
timeout, retry, or drop the call — the surfaced number is off by 2x
from the timer that fired.

Surface the real bound: "Timeout (240s)". Adds a regression test that
stubs fetch to a permanently-pending promise, fast-forwards only the
240_000 ms abort timer (leaves the leading exponential retry delays
on their real values), and asserts the surfaced error string matches
the configured bound.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant