pbakaus/impeccable · error

comp-spec: no region {id}; ids: {ids}

Error message

comp-spec: no region {id}; ids: {ids}

What it means

When cropping, comp-spec looks up the region whose "id" matches the --crop value in spec.regions. If no region has that id, this error lists all valid region ids so the caller can pick the right one. It guards against typos and stale specs.

Source

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

            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)));
        let Some(region) = region else {
            io.err(&format!("comp-spec: no region {id}\n"));
            return 1;
        };
        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);

View on GitHub (pinned to 2bc2879276)

Solutions

  1. Use one of the ids listed in the error's `ids:` suffix.
  2. Run `comp-spec --print` to see the current spec and its exact region ids.
  3. If the id should exist, re-run `comp-spec --comp <png> --regions regions.json` to refresh the spec, then retry.
  4. Fix the id in your regions.json and regenerate the spec.

Example fix

// before
comp-spec --crop Exploded-Plate   // case mismatch, spec has 'exploded-plate'
// after
comp-spec --crop exploded-plate
Defensive patterns

Strategy: validation

Validate before calling

const spec = JSON.parse(fs.readFileSync(specPath, 'utf8'));
const ids = new Set((spec.regions ?? []).map(r => r.id));
if (!ids.has(cropId)) {
  throw new Error(`unknown region '${cropId}'; valid ids: ${[...ids].join(', ')}`);
}

Prevention

When it happens

Trigger: `comp-spec --crop <id>` where <id> does not exactly match any region id string in the spec's regions array — including case mismatches, ids from an older spec, or regions renamed in regions.json after the spec was regenerated.

Common situations: Typos in the region id; copying an id from an old spec after re-running --regions with new ids; forgetting that ids are case-sensitive; using the --plate-prompt id name space interchangeably when the spec changed.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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