{"record":{"id":"df084b7f80ff64e9","repo":"pbakaus/impeccable","slug":"comp-diff-cannot-read-spec-sp-e","errorCode":null,"errorMessage":"comp-diff: cannot read spec {sp}: {e}\n","messagePattern":"comp-diff: cannot read spec (.+?): (.+?)\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/comp-verbs/src/comp_diff.rs","lineNumber":716,"sourceCode":"            io.err(&format!(\"comp-diff: cannot read comp {comp_path}: {e}\\n\"));\n            return 1;\n        }\n    };\n    let build = match read_png(io, build_path) {\n        Ok(v) => v,\n        Err(e) => {\n            io.err(&format!(\"comp-diff: cannot read build {build_path}: {e}\\n\"));\n            return 1;\n        }\n    };\n    let mut spec: Option<Value> = None;\n    let spec_path = arg(argv, \"spec\");\n    if let Some(sp) = spec_path {\n        match std::fs::read_to_string(resolve(io, sp)) {\n            Ok(raw) => match serde_json::from_str::<Value>(&raw) {\n                Ok(v) => spec = Some(v),\n                Err(e) => {\n                    io.err(&format!(\"comp-diff: cannot read spec {sp}: {e}\\n\"));\n                    return 1;\n                }\n            },\n            Err(e) => {\n                io.err(&format!(\"comp-diff: cannot read spec {sp}: {e}\\n\"));\n                return 1;\n            }\n        }\n    }\n    let default_out = {\n        let d = Path::new(build_path).parent().map(|p| p.to_path_buf()).unwrap_or_default();\n        d.join(\"diff\").to_string_lossy().replace('\\\\', \"/\")\n    };\n    let out_dir = arg_or(argv, \"out-dir\", &default_out).to_string();\n    let default_label = Path::new(build_path)\n        .file_stem()\n        .map(|s| s.to_string_lossy().to_string())\n        .unwrap_or_default();","sourceCodeStart":698,"sourceCodeEnd":734,"githubUrl":"https://github.com/pbakaus/impeccable/blob/2bc2879276c1f321a53c4ca99d3371e411329b52/crates/comp-verbs/src/comp_diff.rs#L698-L734","documentation":"When `--spec <path>` is supplied, comp-diff reads the spec JSON file and parses it. This instance fires when the file read itself fails (missing file, permissions, path is a directory), reporting the path plus the io error and exiting 1. Note the same message is reused for JSON parse failure in the sibling arm.","triggerScenarios":"`--spec <path>` given a path that does not exist or cannot be read (permissions, is a directory); resolve(io, sp) points outside the workspace or to an unwritable/absent location.","commonSituations":"Typo'd spec path; spec not yet generated (comp-spec --regions never ran); running from a different working directory so the relative spec path misses; CI copying only images but not spec.json.","solutions":["Verify the spec file exists at the given path (`ls -l <spec>`).","Generate the spec first: `impeccable comp-spec --comp <png> --regions <json>` which writes .impeccable/build/spec.json.","Use the default .impeccable/build/spec.json path or fix the relative path/working directory.","Check read permissions on the spec file."],"exampleFix":"// before\n$ impeccable comp-diff --comp c.png --build b.png --spec ./specs.json\ncomp-diff: cannot read spec ./specs.json: No such file or directory\n// after\n$ impeccable comp-spec --comp c.png --regions regions.json\n$ impeccable comp-diff --comp c.png --build b.png --spec .impeccable/build/spec.json","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":["file-io","json","spec","cli"],"backgroundTag":"file-not-found","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"}