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

  1. Inspect data.output fully (log the JSON) to see which items were returned — text/refusal items explain the missing image.
  2. If the model refused, adjust the feedback/brief to avoid policy-flagged content and retry.
  3. If output is unexpectedly empty, retry as a fresh call (callFresh) in case the thread state is corrupt.
  4. Confirm the tool config {type:'image_generation', model:'gpt-image-2'} still matches OpenAI's current schema; update if renamed.
  5. 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

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.