{"record":{"id":"9af5522732511730","repo":"tinyhumansai/openhuman","slug":"openai-responses-api-timed-out-after-timeoutms-m","errorCode":null,"errorMessage":"OpenAI Responses API timed out after ${timeoutMs}ms","messagePattern":"OpenAI Responses API timed out after (.+?)ms","errorType":"http","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/release/generate-release-notes.mjs","lineNumber":492,"sourceCode":"  }\n\n  const timeoutMs = 300_000;\n  const controller = new AbortController();\n  const timeout = setTimeout(() => controller.abort(), timeoutMs);\n  let response;\n  try {\n    response = await fetch('https://api.openai.com/v1/responses', {\n      method: 'POST',\n      signal: controller.signal,\n      headers: {\n        Authorization: `Bearer ${key}`,\n        'Content-Type': 'application/json',\n      },\n      body: JSON.stringify(request),\n    });\n  } catch (error) {\n    if (error?.name === 'AbortError') {\n      throw new Error(`OpenAI Responses API timed out after ${timeoutMs}ms`);\n    }\n    throw error;\n  } finally {\n    clearTimeout(timeout);\n  }\n\n  const body = await response.text();\n  let json = null;\n  try {\n    json = JSON.parse(body);\n  } catch {\n    // Keep the raw body in the error below.\n  }\n\n  if (!response.ok) {\n    const message = json?.error?.message || body;\n    throw new Error(`OpenAI Responses API failed (${response.status}): ${message}`);\n  }","sourceCodeStart":474,"sourceCodeEnd":510,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/a221052e0df5b1f7598fceba7329fd1af95d6699/scripts/release/generate-release-notes.mjs#L474-L510","documentation":"The fetch() to https://api.openai.com/v1/responses was aborted by the script's own AbortController after 300_000 ms (5 minutes); the resulting AbortError is caught and rethrown as this timeout error. Note the payload is already bounded to MAX_PROMPT_CHARS = 120_000, so this is wall-clock latency, not unbounded input.","triggerScenarios":"A large release range producing a long generation that exceeds 5 minutes; a network stall between the runner and api.openai.com; OpenAI-side degradation on long completions.","commonSituations":"Big-bang merges producing hundreds of PRs in one range; CI runners with constrained or proxied egress; retrying during an OpenAI incident window.","solutions":["Re-run — transient stalls are the most common cause","Shrink the range: --from a more recent tag so fewer PRs are summarized","Use --no-ai to render deterministic notes without calling OpenAI","Check https://status.openai.com if it reproducibly times out on small ranges"],"exampleFix":"# before\nnode scripts/release/generate-release-notes.mjs --from v0.50.0   # 300s timeout over a huge range\n\n# after\nnode scripts/release/generate-release-notes.mjs --from v0.58.0   # smaller window\n# or\nnode scripts/release/generate-release-notes.mjs --from v0.50.0 --no-ai","handlingStrategy":"retry","validationCode":"# bound the work before calling the API — huge ranges are the usual timeout cause\ncount=$(git rev-list --count \"${FROM}..${TO}\")\nif [ \"$count\" -gt 300 ]; then\n  echo \"$count commits — using --no-ai\" >&2\n  exec node scripts/release/generate-release-notes.mjs --from \"$FROM\" --to \"$TO\" --no-ai\nfi","typeGuard":null,"tryCatchPattern":"for attempt in 1 2; do\n  node scripts/release/generate-release-notes.mjs --from \"$FROM\" && break\n  [ \"$attempt\" -eq 2 ] && { echo 'generation failed twice' >&2; exit 1; }\n  echo 'retrying after timeout...' >&2; sleep 60\ndone","preventionTips":["keep release ranges small; cut releases more often","default to --no-ai in latency-sensitive CI lanes","wrap invocation in a bounded retry with backoff"],"tags":["openai","timeout","network","release-notes"],"backgroundTag":null,"analyzedSha":"a221052e0df5b1f7598fceba7329fd1af95d6699","analyzedAt":"2026-08-16T12:47:06.542Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}