heygen-com/hyperframes · error
OpenRouter request failed with HTTP ${res.status}
Error message
OpenRouter request failed with HTTP ${res.status} What it means
Thrown inside the OpenRouter captionOne implementation when the fetch to https://openrouter.ai/api/v1/chat/completions returns a non-2xx HTTP status. The response body is drained (await res.text()) so the connection is released, then the error is raised with just the status code. This path is only reached when OPENROUTER_API_KEY is set (OpenRouter wins over Gemini). The error does not include the response body, so the user must infer the cause from the code (401 auth, 402 quota, 429 rate limit, 5xx provider).
Source
Thrown at packages/cli/src/capture/contentExtractor.ts:329
model,
messages: [
{
role: "user",
content: [
{ type: "text", text: prompt },
{
type: "image_url",
image_url: { url: `data:${mimeType};base64,${base64}` },
},
],
},
],
max_tokens: maxTokens,
}),
});
if (!res.ok) {
await res.text();
throw new Error(`OpenRouter request failed with HTTP ${res.status}`);
}
const data = (await res.json()) as {
choices?: Array<{ message?: { content?: string } }>;
};
return data.choices?.[0]?.message?.content?.trim() || "";
}, timeoutMs);
};
} else {
// Unreachable when geminiKey is unset (guarded above); re-narrow for TS.
if (!geminiKey) return geminiCaptions;
const { GoogleGenAI } = await import("@google/genai");
const ai = new GoogleGenAI({ apiKey: geminiKey });
captionOne = async ({ mimeType, base64, prompt, maxTokens, timeoutMs }) => {
const response = await runBoundedVisionRequest(
(signal) =>
ai.models.generateContent({
model,
contents: [View on GitHub (pinned to c2996c8626)
Solutions
- Check the HTTP status: 401 → fix/rotate OPENROUTER_API_KEY; 402 → add OpenRouter credits; 404 → set HYPERFRAMES_OPENROUTER_MODEL to a valid slug; 429 → slow down / add retries; 5xx → retry shortly.
- Verify the model slug is current: `curl -H "Authorization: Bearer $OPENROUTER_API_KEY" https://openrouter.ai/api/v1/models` and pick a vision-capable model.
- If OpenRouter is unreliable, unset OPENROUTER_API_KEY and use GEMINI_API_KEY/GOOGLE_API_KEY instead (Gemini path).
- For batch captioning hitting 429, reduce concurrency or add backoff in runBoundedVisionRequest.
Example fix
# before — bad/insufficient key $ export OPENROUTER_API_KEY=sk-or-... $ hyperframes render ... # HTTP 401 / 402 # verify key and credits at openrouter.ai, then: $ export OPENROUTER_API_KEY=sk-or-validkey # or override a deprecated model slug $ export HYPERFRAMES_OPENROUTER_MODEL=google/gemini-flash-1.5 $ hyperframes render ... # or switch provider $ unset OPENROUTER_API_KEY $ export GEMINI_API_KEY=... $ hyperframes render ...
Defensive patterns
Strategy: retry
Validate before calling
async function openRouterReachable(key: string): Promise<boolean> {
const res = await fetch('https://openrouter.ai/api/v1/models', {
headers: { Authorization: `Bearer ${key}` },
});
return res.ok;
}
if (process.env.OPENROUTER_API_KEY && !await openRouterReachable(process.env.OPENROUTER_API_KEY)) {
throw new Error('OpenRouter key invalid/exhausted. Fix OPENROUTER_API_KEY or unset it to use Gemini.');
} Try / catch
async function captionWithRetry(args, attempts = 3) {
for (let i = 0; i < attempts; i++) {
try {
return await captionOne(args);
} catch (err) {
const msg = (err as Error).message;
if (/HTTP 429|HTTP 5\d\d/.test(msg) && i < attempts - 1) {
await new Promise((r) => setTimeout(r, 2 ** i * 1000));
continue;
}
throw err;
}
}
throw new Error('unreachable');
} Prevention
- Validate OPENROUTER_API_KEY and check credits before batch runs.
- Confirm the model slug (default google/gemini-3.1-flash-lite) is available; override via HYPERFRAMES_OPENROUTER_MODEL.
- Add exponential backoff for 429/5xx; keep Gemini as a fallback by setting GEMINI_API_KEY and unsetting OPENROUTER_API_KEY.
- Reduce concurrency in batch captioning to stay under rate limits.
When it happens
Trigger: captionImagesWithGemini runs with OPENROUTER_API_KEY set; the vision caption request to OpenRouter returns non-OK — 401 (bad key), 402 (insufficient credits), 404 (model not found, e.g. HYPERFRAMES_OPENROUTER_MODEL set to a nonexistent slug), 429 (rate limit), or 5xx (upstream provider error).
Common situations: Expired or mistyped OPENROUTER_API_KEY; insufficient OpenRouter credits (402); the configured model slug (default google/gemini-3.1-flash-lite) is unavailable for the account or deprecated; rate limiting under batch captioning; upstream model provider outage.
Related errors
- RATE_LIMITED
- [build-zip] npm install into staging failed (status ${result
- Model download failed: ${model}
- Website capture blocked: the loaded page matched an access-p
- Invalid JSON response: ${(err as Error).message}
AI-assisted analysis of heygen-com/hyperframes@c2996c8626 (2026-08-12).
Data as JSON: /api/errors/0593f123871d5556.
Report an issue: GitHub.