{"record":{"id":"7527e9c073760361","repo":"pbakaus/impeccable","slug":"comp-spec-cannot-read-comp-file-e","errorCode":null,"errorMessage":"comp-spec: cannot read {comp_file}: {e}\n","messagePattern":"comp-spec: cannot read (.+?): (.+?)\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/comp-verbs/src/comp_spec.rs","lineNumber":835,"sourceCode":"        io.out(&format!(\"{}\\n\", plate_prompt(&spec, region)));\n        return 0;\n    }\n    if let Some(id) = arg(argv, \"crop\") {\n        let Some(spec) = load_spec(&resolve(io, &spec_path)) else {\n            io.err(&format!(\"comp-spec: no spec at {spec_path}\\n\"));\n            return 1;\n        };\n        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();\n        let Some(region) = region else {\n            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();\n            io.err(&format!(\"comp-spec: no region {id}; ids: {ids}\\n\"));\n            return 1;\n        };\n        let comp_file = spec.get(\"comp\").and_then(Value::as_str).unwrap_or(\"\");\n        let comp = match png_io::load_raster(&resolve(io, comp_file)) {\n            Ok((d, _)) => d.image,\n            Err(e) => {\n                io.err(&format!(\"comp-spec: cannot read {comp_file}: {e}\\n\"));\n                return 1;\n            }\n        };\n        let medium = region.get(\"medium\").and_then(Value::as_str).unwrap_or(\"\");\n        let mut c = if medium == \"raster\" && !flag(argv, \"raw\") {\n            plate_reference(&comp, &spec, &region)\n        } else {\n            let px = |k: &str| region.pointer(&format!(\"/px/{k}\")).and_then(Value::as_f64).unwrap_or(0.0);\n            r::crop(&comp, px(\"x\"), px(\"y\"), px(\"w\"), px(\"h\"))\n        };\n        let scale = util::parse_f64(arg_or(argv, \"scale\", \"1\"), 1.0);\n        if scale > 1.0 {\n            c = r::resize(&c, c.width as f64 * scale, c.height as f64 * scale);\n        }\n        let default_out = join_path(&join_path(BUILD_DIR, \"crops\"), &format!(\"{id}.png\"));\n        let out = arg_or(argv, \"out\", &default_out).to_string();\n        let out_path = resolve(io, &out);\n        if let Some(parent) = out_path.parent() {","sourceCodeStart":817,"sourceCodeEnd":853,"githubUrl":"https://github.com/pbakaus/impeccable/blob/2bc2879276c1f321a53c4ca99d3371e411329b52/crates/comp-verbs/src/comp_spec.rs#L817-L853","documentation":"For --crop mode, the spec records which PNG the regions were measured against (its \"comp\" field). comp-spec re-loads that image to extract the region; this error is thrown when png_io::load_raster fails on that recorded path — the file is missing, unreadable, or not a decodable raster.","triggerScenarios":"The comp PNG referenced in spec.json was moved, deleted, or renamed after the spec was generated; the \"comp\" path is relative and the current working directory differs; the file exists but is not a valid PNG (truncated download, wrong format, zero bytes).","commonSituations":"Cleaning up source images but keeping the spec; running the crop from a different directory so the relative \"comp\" path no longer resolves; committing the spec to git but not the (large) comp PNG.","solutions":["Restore the comp PNG at the path recorded in the spec's \"comp\" field, or move the spec back next to it.","Run --crop from the same working directory where --regions was originally run.","Regenerate the spec with `comp-spec --comp <valid.png> --regions regions.json` pointing at the image's current location.","Verify the file is a real PNG (non-zero size, PNG magic bytes) if the path is correct."],"exampleFix":"// before\n{ \"comp\": \"../shots/comp.png\", ... }   // file since moved to shots/final/comp.png\n// after\nregenerate: comp-spec --comp shots/final/comp.png --regions regions.json","handlingStrategy":"validation","validationCode":"const spec = JSON.parse(fs.readFileSync(specPath, 'utf8'));\nconst compPath = path.resolve(spec.comp);\nif (!fs.existsSync(compPath)) {\n  throw new Error(`comp image from spec missing: ${compPath}; re-run --regions to regenerate`);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep the comp PNG alongside the spec and commit both (or regenerate both together).","Run --crop from the same directory where the spec was created.","Regenerate the spec whenever the comp image moves or is renamed.","Verify the comp file is a valid non-empty PNG before cropping."],"tags":["cli","file-read","png"],"backgroundTag":"file-read-failed","analyzedSha":"2bc2879276c1f321a53c4ca99d3371e411329b52","analyzedAt":"2026-09-08T04:51:14.109Z","contentChangedAt":"2026-09-08T04:51:14.109Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}