pbakaus/impeccable · error

comp-spec: cannot read regions {rf}: {e}

Error message

comp-spec: cannot read regions {rf}: {e}

What it means

In --regions mode, comp-spec reads the regions JSON file and parses it with serde_json. This error is thrown when the file exists but its contents are not valid JSON (parse branch), so region measurement cannot proceed. The underlying serde message is appended after the path.

Source

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

            .into_iter()
            .filter(|b| b.strength > 0.2)
            .map(|b| format!("{}%", round(b.y * 100.0) as i64))
            .collect::<Vec<_>>()
            .join(" ");
        io.out(&format!("BANDS {}\n", if bands_str.is_empty() { "none".to_string() } else { bands_str }));
        io.out("NEXT open the grid image, then write regions.json in exactly this shape and run --regions regions.json:\n");
        io.out("  { \"regions\": [ { \"id\": \"exploded-plate\", \"kind\": \"plate\", \"grid\": \"E0:H4\", \"note\": \"exploded carburetor drawing\" }, { \"id\": \"masthead\", \"kind\": \"chrome\", \"grid\": \"A0:J0\", \"note\": \"navy bar\" } ] }\n");
        io.out("  kind: plate | image | texture (painted material: every illustration, photograph, figure, product object, texture; each ships as a raster plate) or text | control | chrome (code draws it). grid: <colrow>:<colrow>, A0 top-left to J9 bottom-right, inclusive.\n");
        io.out("  A texture region is a clean sample cell of the material (ground with no ink on it), not the whole band it covers; the page tiles it. Ink that sits on the material gets its own text/control region.\n");
        return 0;
    }

    let regions_input: Value = if let Some(rf) = arg(argv, "regions") {
        match std::fs::read_to_string(resolve(io, rf)) {
            Ok(raw) => match serde_json::from_str(&raw) {
                Ok(v) => v,
                Err(e) => {
                    io.err(&format!("comp-spec: cannot read regions {rf}: {e}\n"));
                    return 1;
                }
            },
            Err(e) => {
                io.err(&format!("comp-spec: cannot read regions {rf}: {e}\n"));
                return 1;
            }
        }
    } else if flag(argv, "auto") {
        auto_regions(&comp)
    } else {
        io.err("comp-spec: pass --grid to get the coordinate grid, then --regions <json> (or --auto for band regions)\n");
        return 1;
    };
    let spec = match measure_regions(&comp, &regions_input, comp_path) {
        Ok(s) => s,
        Err(e) => {
            io.err(&format!("comp-spec: {e}\n"));

View on GitHub (pinned to 2bc2879276)

Solutions

  1. Validate the file with a JSON parser (`node -e 'JSON.parse(require("fs").readFileSync("regions.json"))'`) and fix the reported syntax error.
  2. Remove trailing commas, comments, and single quotes; ensure double-quoted keys.
  3. Strip any UTF-8 BOM from the file.
  4. Start from the exact shape shown by `comp-spec --help`: { "regions": [ { "id", "kind", "grid", "note" } ] }.

Example fix

// before
{ regions: [ { "id": "art", "grid": "E0:J4", } ], }   // unquoted key + trailing commas
// after
{ "regions": [ { "id": "art", "kind": "plate", "grid": "E0:J4" } ] }
Defensive patterns

Strategy: validation

Validate before calling

const raw = fs.readFileSync(regionsFile, 'utf8').replace(/^\uFEFF/, ''); // strip BOM
const spec = JSON.parse(raw);                       // throws with position on invalid JSON
if (!Array.isArray(spec.regions)) throw new Error('regions file must be { "regions": [...] }');
for (const r of spec.regions) {
  if (!r.id || !r.grid) throw new Error(`region missing id/grid: ${JSON.stringify(r)}`);
}

Prevention

When it happens

Trigger: `comp-spec --regions <file>` where <file> contains syntactically invalid JSON: trailing commas, single quotes, comments, BOM bytes, JSON5-style input, or a truncated write.

Common situations: Hand-authoring regions.json and making a syntax slip; copying the example out of the help text including the surrounding prose; editors saving with a UTF-8 BOM; an interrupted write leaving a partial file.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


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