garrytan/gstack · error
No image data in threaded response
Error message
No image data in threaded response
What it means
Thrown by callThreaded() when OpenAI returned HTTP 200 from /v1/responses but the output array has no item of type 'image_generation_call' with a truthy .result. It is a shape contract failure: a successful status code did not carry the image bytes the caller needs, so the function refuses to return an empty/undefined payload. Common because the Responses API can legally return text/reasoning without invoking the image tool.
Source
Thrown at design/src/iterate.ts:119
});
if (!response.ok) {
const error = await response.text();
if (response.status === 403 && error.includes("organization must be verified")) {
throw new Error(
"OpenAI organization verification required.\n"
+ "Go to https://platform.openai.com/settings/organization to verify.\n"
+ "After verification, wait up to 15 minutes for access to propagate.",
);
}
throw new Error(`API error (${response.status}): ${error.slice(0, 300)}`);
}
const data = await response.json() as any;
const imageItem = data.output?.find((item: any) => item.type === "image_generation_call");
if (!imageItem?.result) {
throw new Error("No image data in threaded response");
}
return { responseId: data.id, imageData: imageItem.result };
} finally {
clearTimeout(timeout);
}
}
async function callFresh(
apiKey: string,
prompt: string,
): Promise<{ responseId: string; imageData: string }> {
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 240_000);
try {
const response = await fetch("https://api.openai.com/v1/responses", {
method: "POST",View on GitHub (pinned to 94993f7401)
Solutions
- Inspect data.output fully (log the JSON) to see which items were returned — text/refusal items explain the missing image.
- If the model refused, adjust the feedback/brief to avoid policy-flagged content and retry.
- If output is unexpectedly empty, retry as a fresh call (callFresh) in case the thread state is corrupt.
- Confirm the tool config {type:'image_generation', model:'gpt-image-2'} still matches OpenAI's current schema; update if renamed.
- Add max_output_tokens or other tool-invocation parameters if the model is truncating before the image call.
Example fix
// before
const data = await response.json() as any;
const imageItem = data.output?.find((item: any) => item.type === "image_generation_call");
if (!imageItem?.result) throw new Error("No image data in threaded response");
// after — capture why the image is missing for diagnostics
const data = await response.json() as any;
const imageItem = data.output?.find((item: any) => item.type === "image_generation_call");
if (!imageItem?.result) {
const reasons = (data.output ?? []).map((i: any) => `${i.type}:${i.status ?? 'n/a'}`).join(', ');
throw new Error(`No image data in threaded response (output items: ${reasons || 'none'})`);
} Defensive patterns
Strategy: validation
Type guard
function hasImageResult(data: any): boolean {
return Array.isArray(data?.output) &&
data.output.some((i: any) => i?.type === 'image_generation_call' && typeof i?.result === 'string' && i.result.length > 0);
} Try / catch
try {
return await callThreaded(apiKey, prevId, feedback);
} catch (e) {
if (e instanceof Error && e.message.startsWith('No image data in threaded response')) {
// Thread produced no image — retry fresh instead of threading
return callFresh(apiKey, buildAccumulatedPrompt(brief, feedback));
}
throw e;
} Prevention
- Sanitize feedback to avoid content-filter trip words before sending.
- Retry once via callFresh when a threaded call yields no image.
- Log data.output shape when this fires to catch schema drift early.
- Pin to a known-good gpt-image-2 schema and update on OpenAI release notes.
When it happens
Trigger: 200 OK where data.output either is missing, empty, contains only reasoning/text items, or contains an image_generation_call whose .result is null/empty (e.g. tool was skipped, content filter suppressed output, or model returned a refusal). Also if an API schema revision renames 'image_generation_call' or nests .result differently.
Common situations: Prompt tripped OpenAI's content filter so the image tool was not invoked; feedback text asked for disallowed content and the model refused; a thread that previously produced images switched to text-only on a follow-up; gpt-image-2 model name deprecated/renamed upstream; partial response due to max_output_tokens cutoff.
Related errors
AI-assisted analysis of garrytan/gstack@94993f7401 (2026-08-12).
Data as JSON: /api/errors/a84efcbf6bc7322b.
Report an issue: GitHub.