pbakaus/impeccable · warning

generate-image: failed to embed prompt in the image

Error message

generate-image: failed to embed prompt in the image

What it means

After successfully writing the generated image, generate-image attempts to embed the prompt metadata into the image file via the embed_prompt module. If that sub-run exits non-zero, it warns that the prompt could not be embedded (the image itself is still written). This is a warning-level side effect, not a generation failure.

Source

Thrown at crates/context/src/generate_image.rs:385

    let b64 = json.get("data").and_then(|d| d.get(0)).and_then(|d| d.get("b64_json")).and_then(|b| b.as_str()).filter(|s| !s.is_empty());
    let Some(b64) = b64 else {
        io.err("generate-image: no image in response\n");
        return 1;
    };
    let bytes = base64_decode(b64);
    let _ = std::fs::write(abs(&out), bytes);
    // best-effort embed + sidecar
    // JS-PARITY: generate-image.mjs#676 reports whether the embed actually
    // succeeded. The install-path-with-spaces half of #676 is a JS-only
    // subprocess concern (fileURLToPath vs URL.pathname); the engine embeds
    // in-process, so only the success tracking and message carry over here.
    let embedded;
    {
        let mut sub_io = Io::captured("", io.cwd.clone(), io.env.clone()).0;
        let ret = crate::embed_prompt::run(&[out.clone(), "--prompt".to_string(), prompt.clone()], &mut sub_io);
        embedded = ret == 0;
        if !embedded {
            io.err("generate-image: failed to embed prompt in the image\n");
        }
        let mut m = Map::new();
        m.insert("prompt".into(), Value::String(prompt.clone()));
        m.insert("createdAt".into(), Value::String(iso_now()));
        m.insert("tool".into(), Value::String("impeccable generate-image".into()));
        m.insert("model".into(), Value::String("gpt-image-2".into()));
        if !refs.is_empty() {
            m.insert("refs".into(), Value::Array(refs.iter().cloned().map(Value::String).collect()));
        }
        let _ = std::fs::write(abs(&format!("{}.json", out)), json_pretty(&Value::Object(m)));
    }
    io.out(&format!(
        "IMAGE: {} ({}, {}, gpt-image-2, billed to your OpenAI key); {} at {}.json\n",
        out,
        size,
        quality,
        if embedded { "prompt embedded + sidecar" } else { "sidecar" },
        out

View on GitHub (pinned to 2bc2879276)

Solutions

  1. Check the embed_prompt output/logs to see why embedding failed and fix the underlying cause (permissions, disk space, format).
  2. Verify the output file format is one the embedder supports (e.g. PNG).
  3. Re-run the embed step manually: `impeccable embed-prompt <out> --prompt "..."`.
  4. If metadata embedding is optional, treat this as a warning — the image file itself was generated successfully.
  5. Ensure the output directory remains writable after generation (some workflows lock or upload files immediately).

Example fix

// before
impeccable generate-image --prompt "p" --out out.svg
// generate-image: failed to embed prompt in the image
// after
impeccable generate-image --prompt "p" --out out.png  # embeddable format
Defensive patterns

Strategy: try-catch

Validate before calling

const fmt = path.extname(out).toLowerCase();
if (!".png".includes(fmt.slice(1)) && fmt !== ".png") {
  console.warn(`embed-prompt may not support ${fmt}; expect a warning`);
}

Try / catch

const r = spawnSync("impeccable", ["generate-image", ...], { encoding: "utf8" });
if (r.status !== 0) throw new Error(r.stderr);
if (r.stderr.includes("failed to embed prompt")) {
  console.warn("image generated but prompt metadata not embedded — re-run embed-prompt if needed");
}

Prevention

When it happens

Trigger: `crate::embed_prompt::run(...)` returns a non-zero exit code for the freshly written image — unsupported/corrupt image format for embedding, write failure of the modified file, or an embed tool bug.

Common situations: Generating to an .svg or format the embedder can't annotate; disk full or permission issue when the embedder rewrites the file; the output path changed between write and embed; version mismatch between generator and embedder expectations.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of pbakaus/impeccable@2bc2879276 (2026-09-08). Data as JSON: /api/errors/5005ded4a566c1da. Report an issue: GitHub.