{"record":{"id":"0792201b10ea39a9","repo":"pbakaus/impeccable","slug":"error-079220","errorCode":null,"errorMessage":"{}\n","messagePattern":"\\{\\}\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/context/src/critique_storage.rs","lineNumber":472,"sourceCode":"                None => {\n                    io.err(\"no stable slug for input\\n\");\n                    1\n                }\n            }\n        }\n        \"write\" => {\n            let slug_arg = rest.first().map(String::as_str).unwrap_or(\"\");\n            let slug = coerce_slug(rest.first().map(String::as_str), &cwd);\n            let body_file = rest.get(1).filter(|s| !s.is_empty());\n            let (Some(slug), Some(body_file)) = (slug, body_file) else {\n                io.err(\"usage: write <slug-or-target> <body-file>\\n\");\n                return 1;\n            };\n            let raw = match std::fs::read(body_file) {\n                Ok(b) => String::from_utf8_lossy(&b).into_owned(),\n                Err(e) => {\n                    // JS: uncaught exception -> stack trace on stderr, exit 1\n                    io.err(&format!(\"{}\\n\", uncaught(&node_read_error(body_file, &e))));\n                    return 1;\n                }\n            };\n            let mut parsed_meta: Map<String, Value> = Map::new();\n            if let Some(m) = env.get(\"IMPECCABLE_CRITIQUE_META\").filter(|s| !s.is_empty()) {\n                if let Ok(Value::Object(o)) = serde_json::from_str::<Value>(m) {\n                    parsed_meta = o;\n                }\n            }\n            // JS #660: the helper, not caller metadata, owns the target\n            // fingerprint/identity. Drop any caller-supplied copies (preserving\n            // the order of the rest) and append the freshly resolved values.\n            let mut meta: Map<String, Value> = Map::new();\n            for (k, v) in parsed_meta {\n                if k != \"target_fingerprint\" && k != \"target_path\" && k != \"target_identity\" {\n                    meta.insert(k, v);\n                }\n            }","sourceCodeStart":454,"sourceCodeEnd":490,"githubUrl":"https://github.com/pbakaus/impeccable/blob/2bc2879276c1f321a53c4ca99d3371e411329b52/crates/context/src/critique_storage.rs#L454-L490","documentation":"In the critique-storage `write` flow, reading the body file with `std::fs::read` can fail; on failure the code builds a Node-style 'uncaught exception' message via `uncaught(&node_read_error(body_file, &e))` — mirroring the original JS behavior of a stack trace on stderr — and prints it through this `{}` wrapper with exit 1. The visible text is the formatted read error (e.g. ENOENT for the body file).","triggerScenarios":"Calling `write <slug> <body-file>` where body-file doesn't exist, is a directory, or isn't readable due to permissions; the path was computed relative to a different cwd than the one the CLI runs in; a variable interpolated an empty/incorrect path that slipped past the emptiness check.","commonSituations":"Typoed body-file path; generating the body file in a temp dir that was cleaned before write; running the CLI from a different directory than the script that created the file; permission-restricted critique directories.","solutions":["Verify the body-file path exists and is readable before invoking (`test -r <file>`).","Pass an absolute path, or run from the directory where the body file was created.","Create the body file first if your pipeline assumes it exists.","Check file permissions if the path exists but the process user can't read it."],"exampleFix":"// before\ncontext critique write my-app-web ./kritique.md\n// uncaught: ENOENT ... kritique.md\n// after\ncontext critique write my-app-web ./critique.md","handlingStrategy":"validation","validationCode":"import { accessSync, constants } from 'node:fs';\ntry {\n  accessSync(bodyFile, constants.R_OK);\n} catch {\n  throw new Error(`body file not readable: ${bodyFile}`);\n}","typeGuard":"function bodyFileReadable(p) {\n  try { accessSync(p, constants.R_OK); return true; } catch { return false; }\n}","tryCatchPattern":"try {\n  const body = readFileSync(bodyFile, 'utf8');\n} catch (e) {\n  // mirror of the CLI's node_read_error: ENOENT vs EACCES vs EISDIR\n  console.error(`Cannot read ${bodyFile}: ${e.code ?? e.message}`);\n  process.exit(1);\n}","preventionTips":["Use absolute paths for the body file so cwd differences can't break resolution.","Ensure the body file is written and flushed before invoking the write subcommand.","Check readability (not just existence) when files may come from other users or temp dirs."],"tags":["cli","file-read","file-not-found"],"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"}