{"record":{"id":"2124d09c8f5717d4","repo":"pbakaus/impeccable","slug":"comp-diff-cannot-read-build-build-path-e","errorCode":null,"errorMessage":"comp-diff: cannot read build {build_path}: {e}\n","messagePattern":"comp-diff: cannot read build (.+?): (.+?)\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/comp-verbs/src/comp_diff.rs","lineNumber":705,"sourceCode":"/// `impeccable comp-diff --comp <png> --build <png> ...`\npub fn run(argv: &[String], io: &mut Io) -> i32 {\n    let comp_path = arg(argv, \"comp\");\n    let build_path = arg(argv, \"build\");\n    let (Some(comp_path), Some(build_path)) = (comp_path, build_path) else {\n        io.err(\"usage: comp-diff.mjs --comp <png> --build <png> [--spec spec.json] [--out-dir dir] [--align top|stretch] [--label name] [--threshold 0.75] [--json]\\n\");\n        return 1;\n    };\n    let comp = match read_png(io, comp_path) {\n        Ok(v) => v,\n        Err(e) => {\n            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            }","sourceCodeStart":687,"sourceCodeEnd":723,"githubUrl":"https://github.com/pbakaus/impeccable/blob/2bc2879276c1f321a53c4ca99d3371e411329b52/crates/comp-verbs/src/comp_diff.rs#L687-L723","documentation":"Same read/decode guard as the comp image, but applied to the `--build` PNG — the screenshot of the built page being compared against the comp. On read or decode failure it prints the build path plus the io error and exits 1.","triggerScenarios":"`--build <path>` points at a nonexistent file, an unreadable path, a non-PNG format, or a corrupted/truncated PNG; the built screenshot step failed silently upstream and produced no file.","commonSituations":"The screenshot/dev-server capture step failed or wrote to a different directory; CI artifact wasn't downloaded; stale script referencing an old output filename; image saved in another format.","solutions":["Verify the build PNG path exists and is readable.","Confirm the format with `file <path>` — must be PNG image data.","Re-run the screenshot capture step that produces the build image.","Check that the pipeline that generates the build PNG ran before comp-diff."],"exampleFix":"// before\n$ impeccable comp-diff --comp ./comp.png --build ./old-shot.png\ncomp-diff: cannot read build ./old-shot.png: No such file or directory\n// after\n$ bun run screenshots && impeccable comp-diff --comp ./comp.png --build ./.impeccable/build/page.png","handlingStrategy":"validation","validationCode":"import { existsSync, readFileSync } from 'node:fs';\nif (!existsSync(buildPath)) throw new Error(`build screenshot missing: ${buildPath}`);\nconst magic = readFileSync(buildPath).subarray(0, 8);\nif (!magic.equals(Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]))) {\n  throw new Error(`${buildPath} is not a valid PNG`);\n}","typeGuard":"function isPngFile(p) {\n  try { return readFileSync(p).subarray(0, 8).toString('hex') === '89504e470d0a1a0a'; }\n  catch { return false; }\n}","tryCatchPattern":"try {\n  runSync('impeccable', ['comp-diff', '--comp', comp, '--build', build]);\n} catch (e) {\n  if (/cannot read build/.test(e.stderr ?? '')) {\n    console.error(`Build screenshot unreadable: ${build}. Re-run the screenshot step.`);\n    process.exit(1);\n  }\n  throw e;\n}","preventionTips":["Make the screenshot capture step a hard prerequisite in CI (fail the job if it produces no file).","Use deterministic output paths for build screenshots.","Check file size > 0 and PNG magic before comparing.","Re-download CI artifacts completely before comparing."],"tags":["file-io","png","image-comparison","cli"],"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-14T05:17:10.506Z"}