pbakaus/impeccable · error
comp-spec: {e}
Error message
comp-spec: {e}
What it means
After cropping (and optionally scaling) the region, comp-spec encodes the result as PNG with embedded provenance text via png_io::encode_png. This error surfaces any encoder failure, aborting the crop before the output file is written.
Source
Thrown at crates/comp-verbs/src/comp_spec.rs:862
r::crop(&comp, px("x"), px("y"), px("w"), px("h"))
};
let scale = util::parse_f64(arg_or(argv, "scale", "1"), 1.0);
if scale > 1.0 {
c = r::resize(&c, c.width as f64 * scale, c.height as f64 * scale);
}
let default_out = join_path(&join_path(BUILD_DIR, "crops"), &format!("{id}.png"));
let out = arg_or(argv, "out", &default_out).to_string();
let out_path = resolve(io, &out);
if let Some(parent) = out_path.parent() {
let _ = std::fs::create_dir_all(parent);
}
let text = vec![("impeccable:crop-of".to_string(), format!("{comp_file}#{id}"))];
match png_io::encode_png(&c, &text) {
Ok(bytes) => {
let _ = std::fs::write(&out_path, bytes);
}
Err(e) => {
io.err(&format!("comp-spec: {e}\n"));
return 1;
}
}
io.out(&format!("CROP {out} ({}x{}) region {id} of {comp_file}. Reference only: regenerate the plate from it, never ship it.\n", c.width, c.height));
return 0;
}
let comp_path = arg(argv, "comp");
let Some(comp_path) = comp_path else {
io.err("usage: comp-spec.mjs --comp <png> (--grid | --regions <json> | --auto) [--spec out.json]\n comp-spec.mjs --print | --crop <id> [--out file] [--scale n] | --plate-prompt <id>\n");
return 1;
};
let comp = match png_io::load_raster(&resolve(io, comp_path)) {
Ok((d, _)) => d.image,
Err(e) => {
io.err(&format!("comp-spec: cannot read {comp_path}: {e}\n"));
return 1;
}View on GitHub (pinned to 2bc2879276)
Solutions
- Re-encode or re-export the source comp PNG with a standard tool (e.g. ImageMagick `convert comp.png comp.png`) and regenerate the spec.
- Retry with a smaller crop/scale (lower --scale value) to rule out size-related encoder failures.
- Rebuild or reinstall the engine binary if the failure is reproducible across inputs.
- Check the underlying error text after `comp-spec:` for the specific encoder cause.
Example fix
// before comp-spec --crop art --scale 64 // enormous upscaled crop // after comp-spec --crop art --scale 2
Defensive patterns
Strategy: try-catch
Try / catch
const r = spawnSync('impeccable', ['comp-spec', '--crop', id, '--out', out]);
if (r.status !== 0) {
const msg = r.stderr.toString();
if (msg.startsWith('comp-spec:') && !msg.includes('no spec') && !msg.includes('no region')) {
// encoder-side failure: fall back to re-exporting the source PNG and retry once
}
throw new Error(msg.trim());
} Prevention
- Use standard 8-bit RGBA PNGs as comp sources.
- Keep --scale values modest (1-4x) rather than extreme upscales.
- Re-export source images with a standard encoder if crops fail reproducibly.
- Confirm the output directory is writable; comp-spec ignores fs::write errors by design.
When it happens
Trigger: png_io::encode_png fails while encoding the cropped region image — e.g. an internal raster/encoder error such as an unsupported pixel format or an encoder panic converted to an error. This is rare and mostly indicates a problem with the source raster rather than user input.
Common situations: Corrupt or exotic source PNGs that decode into an unexpected pixel layout; extremely large crops combined with --scale producing allocations/encoder limits; engine build issues with the PNG encoder.
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
- comp-diff: cannot read comp {comp_path}: {e}
- comp-diff: cannot read build {build_path}: {e}
- comp-spec: cannot read {comp_file}: {e}
- comp-spec: cannot read {comp_path}: {e}
- embed-prompt: no embedded prompt found
AI-assisted analysis of pbakaus/impeccable@2bc2879276 (2026-09-08).
Data as JSON: /api/errors/bbed6de6672fb44a.
Report an issue: GitHub.