pbakaus/impeccable · error

comp-spec: cannot read {comp_file}: {e}

Error message

comp-spec: cannot read {comp_file}: {e}

What it means

For --crop mode, the spec records which PNG the regions were measured against (its "comp" field). comp-spec re-loads that image to extract the region; this error is thrown when png_io::load_raster fails on that recorded path — the file is missing, unreadable, or not a decodable raster.

Source

Thrown at crates/comp-verbs/src/comp_spec.rs:835

        io.out(&format!("{}\n", plate_prompt(&spec, region)));
        return 0;
    }
    if let Some(id) = arg(argv, "crop") {
        let Some(spec) = load_spec(&resolve(io, &spec_path)) else {
            io.err(&format!("comp-spec: no spec at {spec_path}\n"));
            return 1;
        };
        let region = spec.get("regions").and_then(Value::as_array).and_then(|a| a.iter().find(|r| r.get("id").and_then(Value::as_str) == Some(id))).cloned();
        let Some(region) = region else {
            let ids = spec.get("regions").and_then(Value::as_array).map(|a| a.iter().filter_map(|r| r.get("id").and_then(Value::as_str)).collect::<Vec<_>>().join(", ")).unwrap_or_default();
            io.err(&format!("comp-spec: no region {id}; ids: {ids}\n"));
            return 1;
        };
        let comp_file = spec.get("comp").and_then(Value::as_str).unwrap_or("");
        let comp = match png_io::load_raster(&resolve(io, comp_file)) {
            Ok((d, _)) => d.image,
            Err(e) => {
                io.err(&format!("comp-spec: cannot read {comp_file}: {e}\n"));
                return 1;
            }
        };
        let medium = region.get("medium").and_then(Value::as_str).unwrap_or("");
        let mut c = if medium == "raster" && !flag(argv, "raw") {
            plate_reference(&comp, &spec, &region)
        } else {
            let px = |k: &str| region.pointer(&format!("/px/{k}")).and_then(Value::as_f64).unwrap_or(0.0);
            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() {

View on GitHub (pinned to 2bc2879276)

Solutions

  1. Restore the comp PNG at the path recorded in the spec's "comp" field, or move the spec back next to it.
  2. Run --crop from the same working directory where --regions was originally run.
  3. Regenerate the spec with `comp-spec --comp <valid.png> --regions regions.json` pointing at the image's current location.
  4. Verify the file is a real PNG (non-zero size, PNG magic bytes) if the path is correct.

Example fix

// before
{ "comp": "../shots/comp.png", ... }   // file since moved to shots/final/comp.png
// after
regenerate: comp-spec --comp shots/final/comp.png --regions regions.json
Defensive patterns

Strategy: validation

Validate before calling

const spec = JSON.parse(fs.readFileSync(specPath, 'utf8'));
const compPath = path.resolve(spec.comp);
if (!fs.existsSync(compPath)) {
  throw new Error(`comp image from spec missing: ${compPath}; re-run --regions to regenerate`);
}

Prevention

When it happens

Trigger: The comp PNG referenced in spec.json was moved, deleted, or renamed after the spec was generated; the "comp" path is relative and the current working directory differs; the file exists but is not a valid PNG (truncated download, wrong format, zero bytes).

Common situations: Cleaning up source images but keeping the spec; running the crop from a different directory so the relative "comp" path no longer resolves; committing the spec to git but not the (large) comp PNG.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


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