{"record":{"id":"464f6a3a2a77b8b0","repo":"can1357/oh-my-pi","slug":"openrouter-image-request-failed-resp-status","errorCode":null,"errorMessage":"OpenRouter image request failed (${resp.status}): ${message}","messagePattern":"OpenRouter image request failed \\((.+?)\\): (.+?)","errorType":"http","errorClass":"ProviderHttpError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/image-gen.ts","lineNumber":1558,"sourceCode":"\t\t\t\t\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\t\t\t\t\t\tAuthorization: `Bearer ${key}`,\n\t\t\t\t\t\t\t\t\t\t...getOpenRouterHeaders(),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tbody: JSON.stringify(requestBody),\n\t\t\t\t\t\t\t\t\tsignal: requestSignal,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\tconst text = await resp.text();\n\t\t\t\t\t\t\t\tif (!resp.ok) {\n\t\t\t\t\t\t\t\t\tlet message = text;\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tconst parsed = JSON.parse(text) as { error?: { message?: string } };\n\t\t\t\t\t\t\t\t\t\tmessage = parsed.error?.message ?? message;\n\t\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\t\t// Keep raw text.\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tthrow new ProviderHttpError(\n\t\t\t\t\t\t\t\t\t\t`OpenRouter image request failed (${resp.status}): ${message}`,\n\t\t\t\t\t\t\t\t\t\tresp.status,\n\t\t\t\t\t\t\t\t\t\t{ headers: resp.headers },\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn text;\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{ signal: requestSignal },\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tconst data = JSON.parse(rawText) as OpenRouterResponse;\n\t\t\t\t\t\tconst message = data.choices?.[0]?.message;\n\t\t\t\t\t\tconst responseText = collectOpenRouterResponseText(message);\n\t\t\t\t\t\tconst imageUrls = extractOpenRouterImageUrls(message);\n\t\t\t\t\t\tconst inlineImages: InlineImageData[] = [];\n\t\t\t\t\t\tfor (const imageUrl of imageUrls) {\n\t\t\t\t\t\t\tinlineImages.push(await loadImageFromUrl(imageUrl, fetchImpl, requestSignal));\n\t\t\t\t\t\t}","sourceCodeStart":1540,"sourceCodeEnd":1576,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/image-gen.ts#L1540-L1576","documentation":"OpenRouter's image generation HTTP endpoint returned a non-2xx response. The tool wraps the status code and the provider's error message (extracted from the JSON error.message field, or the raw body text if unparsable) into a ProviderHttpError, preserving response headers.","triggerScenarios":"Any failed HTTP call to OpenRouter's image API — 401 invalid OPENROUTER_API_KEY, 402 insufficient credits, 404 unknown model slug, 429 rate limit, 5xx upstream — surfacing at image-gen.ts:1558.","commonSituations":"Expired or revoked OpenRouter key; account out of credits for a paid image model; mistyped model id (e.g. wrong vendor prefix); hitting free-tier rate limits; OpenRouter outage.","solutions":["Read the embedded provider message in the error — it states the actual cause (auth, credits, model, rate limit).","Check the key: OPENROUTER_API_KEY valid and active at openrouter.ai/keys.","Check credits/billing on the OpenRouter account for the chosen model.","Verify the model slug exists and supports image generation; fix the model id.","For 429/5xx, retry with backoff; the tool may have already tried other credentialed providers (see aggregate error)."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if (!process.env.OPENROUTER_API_KEY) throw new Error('OPENROUTER_API_KEY required for OpenRouter image requests');","typeGuard":null,"tryCatchPattern":"try {\n  return await openRouterImage(params);\n} catch (err) {\n  if (err instanceof ProviderHttpError) {\n    if (err.status === 429 || err.status >= 500) return retryWithBackoff(() => openRouterImage(params));\n    if (err.status === 401 || err.status === 402) throw new Error(`OpenRouter auth/billing issue: ${err.message}`);\n  }\n  throw err;\n}","preventionTips":["Validate the key and account credits before image workloads","Verify model slugs against OpenRouter's current catalog","Implement backoff for 429/5xx and fail fast on 401/402","Log err.status and headers for support requests"],"tags":["network","http","openrouter","image-generation","provider-error"],"backgroundTag":"http-error-response","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}