pbakaus/impeccable · error

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

Error message

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

What it means

Once --comp is provided, comp-spec loads the composition image via png_io::load_raster. This error is thrown when the image at the --comp path cannot be read or decoded as a raster, preventing grid rendering or region measurement.

Source

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

            }
            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;
        }
    };

    if flag(argv, "grid") {
        let grid_out = resolve(io, GRID_PATH);
        if let Some(parent) = grid_out.parent() {
            let _ = std::fs::create_dir_all(parent);
        }
        match png_io::encode_png(&render_grid(&comp), &[]) {
            Ok(bytes) => {
                let _ = std::fs::write(&grid_out, bytes);
            }
            Err(e) => {
                io.err(&format!("comp-spec: {e}\n"));
                return 1;
            }
        }

View on GitHub (pinned to 2bc2879276)

Solutions

  1. Verify the path exists and is readable (`ls -l <path>`), and run from the intended directory or pass an absolute path.
  2. Convert the image to PNG first (e.g. `magick input.jpg comp.png`) if it is another raster format.
  3. Re-export/re-capture the composition if the file is truncated or zero bytes.
  4. SVG inputs must be rasterized to PNG before use.

Example fix

// before
comp-spec --comp comp.jpg --grid
// after
magick comp.jpg comp.png
comp-spec --comp comp.png --grid
Defensive patterns

Strategy: validation

Validate before calling

import { readFileSync } from 'fs';
const buf = readFileSync(compPath);           // throws if missing/unreadable
if (!(buf.length > 8 && buf[0] === 0x89 && buf[1] === 0x50 && buf[2] === 0x4e && buf[3] === 0x47)) {
  throw new Error(`${compPath} is not a PNG; convert it first`);
}

Type guard

function isPngFile(p) {
  const b = fs.readFileSync(p);
  return b.length > 8 && b[0] === 0x89 && b[1] === 0x50 && b[2] === 0x4e && b[3] === 0x47;
}

Prevention

When it happens

Trigger: --comp points to a nonexistent file, a directory, a file without read permission, or a non-PNG/undecodable file (e.g. a JPEG, SVG, or truncated PNG). Relative paths are resolved against the current working directory, so running from elsewhere also triggers this.

Common situations: Typos in the image path; passing a JPG or SVG exported from a design tool; the screenshot/export step failed silently leaving a zero-byte file; CI running from a different working directory.

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/e6ee619cc83104e8. Report an issue: GitHub.