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

  1. 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.
  2. Retry with a smaller crop/scale (lower --scale value) to rule out size-related encoder failures.
  3. Rebuild or reinstall the engine binary if the failure is reproducible across inputs.
  4. 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

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


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