tinyhumansai/openhuman · error · Error

OpenAI Responses API failed (${response.status}): ${message}

Error message

OpenAI Responses API failed (${response.status}): ${message}

What it means

OpenAI answered the Responses API call with a non-2xx HTTP status; the script surfaces the status code plus the error.message from the JSON body, falling back to the raw body when it is not JSON.

Source

Thrown at scripts/release/generate-release-notes.mjs:509

    if (error?.name === 'AbortError') {
      throw new Error(`OpenAI Responses API timed out after ${timeoutMs}ms`);
    }
    throw error;
  } finally {
    clearTimeout(timeout);
  }

  const body = await response.text();
  let json = null;
  try {
    json = JSON.parse(body);
  } catch {
    // Keep the raw body in the error below.
  }

  if (!response.ok) {
    const message = json?.error?.message || body;
    throw new Error(`OpenAI Responses API failed (${response.status}): ${message}`);
  }

  const text = extractResponseText(json);
  if (!text) {
    throw new Error('OpenAI response did not contain output text');
  }
  return text;
}

export function renderDeterministicNotes({ title, payload }) {
  const newContributors = payload.contributors.filter((contributor) => contributor.isNew);
  const newContributorsSection = newContributors.length
    ? `
## New Contributors 🌟

${newContributors.map((contributor) => renderNewContributorLine(contributor, payload.pullRequests)).join('\n')}

Hope you join the Discord for exclusive roles and contributor rewards!

View on GitHub (pinned to a221052e0d)

Solutions

  1. Map the status: 401/403 → fix the key; 429 → wait, retry, check org billing; 400 → check the --model value; 5xx → retry later
  2. Verify the key independently: curl -s -o /dev/null -w '%{http_code}' -H 'Authorization: Bearer $OPENAI_API_KEY' https://api.openai.com/v1/models
  3. Use --no-ai if the release cannot wait on OpenAI

Example fix

# before
OPENAI_MODEL=some-chat-completions-name node scripts/release/generate-release-notes.mjs   # 400: unknown model

# after — use the default or a valid Responses model
node scripts/release/generate-release-notes.mjs --model gpt-5.2
Defensive patterns

Strategy: try-catch

Validate before calling

# cheap key liveness check before the long generation call
curl -sf -o /dev/null -H "Authorization: Bearer $OPENAI_API_KEY" https://api.openai.com/v1/models \
  || { echo 'OpenAI key invalid or network down' >&2; exit 1; }

Try / catch

out=$(node scripts/release/generate-release-notes.mjs --from "$FROM" 2>&1)
case "$out" in
  *'failed (401)'*|*'failed (403)'*) echo 'fatal: bad key' >&2; exit 2 ;;
  *'failed (429)'*|*'failed (5'*)   sleep 60; node scripts/release/generate-release-notes.mjs --from "$FROM" ;;
  *) printf '%s\n' "$out" ;;
esac

Prevention

When it happens

Trigger: 401/403 from a revoked, mistyped, or region-blocked OPENAI_API_KEY; 429 from rate limits or exhausted org quota; 400 from an invalid --model / OPENAI_MODEL value (default gpt-5.2); 5xx during an OpenAI incident.

Common situations: Expired CI secret; org hit its spend limit; OPENAI_MODEL pointing at a chat/completions-era name the Responses API rejects; key from a free tier without Responses API access.

Related errors


AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16). Data as JSON: /api/errors/f479fc6eb021b3fa. Report an issue: GitHub.