pbakaus/impeccable · error
comp-spec: no spec at {spec_path}
Error message
comp-spec: no spec at {spec_path}
What it means
`comp-spec --plate-prompt <id>` first loads the spec (load_spec) before looking up the requested region. If the spec file cannot be loaded, it emits this shorter variant of the missing-spec message (without the how-to-fix hint) and exits 1. This error is about the spec store, not about the region id.
Source
Thrown at crates/comp-verbs/src/comp_spec.rs:809
/// `impeccable comp-spec ...`
pub fn run(argv: &[String], io: &mut Io) -> i32 {
let spec_path = arg_or(argv, "spec", SPEC_PATH).to_string();
if flag(argv, "help") || argv.is_empty() {
io.out("usage: comp-spec.mjs --comp <png> --grid write .impeccable/build/comp-grid.png (10x10 labeled grid) + palette + bands\n comp-spec.mjs --comp <png> --regions <json> measure regions -> .impeccable/build/spec.json\n regions json: { \"regions\": [ { \"id\": \"art\", \"kind\": \"plate|image|texture|text|control|chrome\", \"grid\": \"E0:J4\", \"note\": \"...\" } ] }\n comp-spec.mjs --comp <png> --auto band regions when you have no regions file\n comp-spec.mjs --print the compact spec\n comp-spec.mjs --crop <id> [--out f] [--scale n] reference crop of a region (never a shipping asset)\n comp-spec.mjs --plate-prompt <id> the regeneration prompt for a raster region\n");
return 0;
}
if flag(argv, "print") {
let Some(spec) = load_spec(&resolve(io, &spec_path)) else {
io.err(&format!("comp-spec: no spec at {spec_path}; run with --comp <png> --regions <json> first\n"));
return 1;
};
io.out(&format!("{}\n", print_spec(&spec)));
return 0;
}
if let Some(id) = arg(argv, "plate-prompt") {
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)));
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();View on GitHub (pinned to 2bc2879276)
Solutions
- Generate the spec first with `comp-spec --comp <png> --regions <json>`.
- Verify the spec path — pass explicit --spec if not using the default .impeccable/build/spec.json.
- Re-run from the correct working directory.
Example fix
// before $ impeccable comp-spec --plate-prompt art comp-spec: no spec at .impeccable/build/spec.json // after $ impeccable comp-spec --comp ./comp.png --regions ./regions.json $ impeccable comp-spec --plate-prompt art
Defensive patterns
Strategy: validation
Validate before calling
import { existsSync } from 'node:fs';
const specPath = args.spec ?? '.impeccable/build/spec.json';
if (!existsSync(specPath)) throw new Error(`spec missing at ${specPath}; generate before --plate-prompt`); Try / catch
const r = spawnSync('impeccable', ['comp-spec', '--plate-prompt', id]);
if (r.status === 1 && /no spec at/.test(r.stderr.toString())) {
runSync('impeccable', ['comp-spec', '--comp', comp, '--regions', regions]);
// then retry the plate-prompt call
} Prevention
- Run comp-spec measure mode before any --plate-prompt usage.
- In CI, restore or regenerate the spec at job start.
- Pass an explicit --spec path when operating outside the default build dir.
When it happens
Trigger: Running `comp-spec --plate-prompt <id>` when no spec exists at spec_path (never generated, deleted, or wrong --spec path / working directory).
Common situations: Same as --print: cleaned build dir, wrong cwd, typo'd --spec path; also automation invoking --plate-prompt before the measure step ran in a fresh CI workspace.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- build-phase: no spec at {SPEC_PATH}; run comp-spec.mjs first
- comp-spec: no spec at {spec_path}; run with --comp <png> --r
- font-match: no spec at {spec_path}; run comp-spec.mjs first
- comp-diff: cannot read spec {sp}: {e}
- comp-spec: no region {id}
AI-assisted analysis of pbakaus/impeccable@2bc2879276 (2026-09-08).
Data as JSON: /api/errors/8c9979b6e63d022d.
Report an issue: GitHub.