pbakaus/impeccable · error
embed-prompt: malformed PNG
Error message
embed-prompt: malformed PNG
What it means
When embedding into a PNG, the CLI parses the chunk list to locate the IEND chunk and rebuild the file idempotently. If no valid IEND chunk offset is found (iend < 8), the file is not a structurally valid PNG and the CLI exits 1 with this message.
Source
Thrown at crates/context/src/embed_prompt.rs:287
return 1;
}
},
_ => None,
},
};
let Some(prompt) = prompt.filter(|p| !p.is_empty()) else {
io.err("embed-prompt: --prompt or --prompt-file required\n");
return 1;
};
let plen = utf16_len(&prompt);
if png {
// JS-PARITY: embed-prompt.mjs#641 finds IEND by walking the PNG
// chunks (not buf.indexOf('IEND')) and reuses parsePng's chunk list
// and prompt to rebuild the body idempotently.
let (chunks, existing) = parse_png(&buf);
let iend: i64 = chunks.iter().find(|c| &c.ty == b"IEND").map(|c| c.offset as i64).unwrap_or(-1);
if iend < 8 {
io.err("embed-prompt: malformed PNG\n");
return 1;
}
let iend = iend as usize;
let mut text_data = KEYWORD.to_vec();
text_data.push(0);
text_data.extend_from_slice(prompt.as_bytes());
let text_chunk = png_chunk(b"tEXt", &text_data);
let out: Vec<u8> = if existing.is_some() {
let mut body: Vec<u8> = Vec::new();
for c in &chunks {
if c.offset < iend && !c.prompt_chunk {
body.extend_from_slice(&buf[c.offset..c.end]);
}
}
let mut o = buf[..8].to_vec();
o.extend_from_slice(&body);
o.extend_from_slice(&text_chunk);
o.extend_from_slice(&png_chunk(b"IEND", &[]));View on GitHub (pinned to 2bc2879276)
Solutions
- Verify the file is a valid PNG (file out.png should say 'PNG image data' and end with IEND).
- Re-export or regenerate the image; do not hand-edit PNG bytes.
- Confirm the image-producing step completed before embedding.
Example fix
// before impeccable embed-prompt --image truncated.png --prompt "x" // after file truncated.png # confirm 'PNG image data' impeccable embed-prompt --image valid.png --prompt "x"
Defensive patterns
Strategy: validation
Validate before calling
const head = fs.readFileSync(f).subarray(0,8); const isPng = head.equals(Buffer.from([0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a]));
Type guard
const isPng = (buf) => buf.length > 8 && buf.subarray(0,8).equals(Buffer.from([0x89,0x50,0x4E,0x47,0x0D,0x0A,0x1A,0x0A]));
Try / catch
try { embedPrompt(img, prompt); } catch (e) { if (/malformed PNG/.test(e.message)) { console.error('re-export the image; it is truncated or not a real PNG'); } throw e; } Prevention
- Verify images with `file` before embedding
- Never truncate or hand-edit PNG bytes
- Confirm the generating step wrote a complete file
When it happens
Trigger: Running `embed-prompt --image <file> --prompt ...` where the file has a .png-ish path/type but is truncated, corrupt, or not actually a PNG (wrong magic bytes or chopped trailing IEND).
Common situations: Partially downloaded/truncated PNGs, files renamed to .png without conversion, images mangled by a prior tool, or passing a JPEG with a .png extension.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- invalid session id: ${id}
- build-phase: finish --disposition ship|fix|rebuild|recapture
- comp-diff: cannot read comp {comp_path}: {e}
- comp-diff: cannot read build {build_path}: {e}
- comp-spec: cannot read {comp_file}: {e}
AI-assisted analysis of pbakaus/impeccable@2bc2879276 (2026-09-08).
Data as JSON: /api/errors/37a58b9d6ef63358.
Report an issue: GitHub.