{"record":{"id":"5005ded4a566c1da","repo":"pbakaus/impeccable","slug":"generate-image-failed-to-embed-prompt-in-the-imag","errorCode":null,"errorMessage":"generate-image: failed to embed prompt in the image\n","messagePattern":"generate-image: failed to embed prompt in the image\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/context/src/generate_image.rs","lineNumber":385,"sourceCode":"    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());\n    let Some(b64) = b64 else {\n        io.err(\"generate-image: no image in response\\n\");\n        return 1;\n    };\n    let bytes = base64_decode(b64);\n    let _ = std::fs::write(abs(&out), bytes);\n    // best-effort embed + sidecar\n    // JS-PARITY: generate-image.mjs#676 reports whether the embed actually\n    // succeeded. The install-path-with-spaces half of #676 is a JS-only\n    // subprocess concern (fileURLToPath vs URL.pathname); the engine embeds\n    // in-process, so only the success tracking and message carry over here.\n    let embedded;\n    {\n        let mut sub_io = Io::captured(\"\", io.cwd.clone(), io.env.clone()).0;\n        let ret = crate::embed_prompt::run(&[out.clone(), \"--prompt\".to_string(), prompt.clone()], &mut sub_io);\n        embedded = ret == 0;\n        if !embedded {\n            io.err(\"generate-image: failed to embed prompt in the image\\n\");\n        }\n        let mut m = Map::new();\n        m.insert(\"prompt\".into(), Value::String(prompt.clone()));\n        m.insert(\"createdAt\".into(), Value::String(iso_now()));\n        m.insert(\"tool\".into(), Value::String(\"impeccable generate-image\".into()));\n        m.insert(\"model\".into(), Value::String(\"gpt-image-2\".into()));\n        if !refs.is_empty() {\n            m.insert(\"refs\".into(), Value::Array(refs.iter().cloned().map(Value::String).collect()));\n        }\n        let _ = std::fs::write(abs(&format!(\"{}.json\", out)), json_pretty(&Value::Object(m)));\n    }\n    io.out(&format!(\n        \"IMAGE: {} ({}, {}, gpt-image-2, billed to your OpenAI key); {} at {}.json\\n\",\n        out,\n        size,\n        quality,\n        if embedded { \"prompt embedded + sidecar\" } else { \"sidecar\" },\n        out","sourceCodeStart":367,"sourceCodeEnd":403,"githubUrl":"https://github.com/pbakaus/impeccable/blob/2bc2879276c1f321a53c4ca99d3371e411329b52/crates/context/src/generate_image.rs#L367-L403","documentation":"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.","triggerScenarios":"`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.","commonSituations":"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.","solutions":["Check the embed_prompt output/logs to see why embedding failed and fix the underlying cause (permissions, disk space, format).","Verify the output file format is one the embedder supports (e.g. PNG).","Re-run the embed step manually: `impeccable embed-prompt <out> --prompt \"...\"`.","If metadata embedding is optional, treat this as a warning — the image file itself was generated successfully.","Ensure the output directory remains writable after generation (some workflows lock or upload files immediately)."],"exampleFix":"// before\nimpeccable generate-image --prompt \"p\" --out out.svg\n// generate-image: failed to embed prompt in the image\n// after\nimpeccable generate-image --prompt \"p\" --out out.png  # embeddable format","handlingStrategy":"try-catch","validationCode":"const fmt = path.extname(out).toLowerCase();\nif (!\".png\".includes(fmt.slice(1)) && fmt !== \".png\") {\n  console.warn(`embed-prompt may not support ${fmt}; expect a warning`);\n}","typeGuard":null,"tryCatchPattern":"const r = spawnSync(\"impeccable\", [\"generate-image\", ...], { encoding: \"utf8\" });\nif (r.status !== 0) throw new Error(r.stderr);\nif (r.stderr.includes(\"failed to embed prompt\")) {\n  console.warn(\"image generated but prompt metadata not embedded — re-run embed-prompt if needed\");\n}","preventionTips":["Generate PNG outputs when prompt embedding matters to your workflow.","Ensure the output directory stays writable after generation.","Treat this warning as non-fatal; re-run `impeccable embed-prompt` manually if metadata is required.","Monitor disk space in CI artifact steps."],"tags":["metadata","embed","warning"],"backgroundTag":"file-write-failed","analyzedSha":"2bc2879276c1f321a53c4ca99d3371e411329b52","analyzedAt":"2026-09-08T04:51:14.109Z","contentChangedAt":"2026-09-08T04:51:14.109Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}