{"record":{"id":"302b02ddd5a265ec","repo":"pbakaus/impeccable","slug":"usage-close-resolved-target-snapshot-file","errorCode":null,"errorMessage":"usage: close <resolved-target> <snapshot-file>\n","messagePattern":"usage: close <resolved-target> <snapshot-file>\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/context/src/critique_storage.rs","lineNumber":615,"sourceCode":"                }\n            }\n            if format_is_json {\n                let mut m = Map::new();\n                m.insert(\"snapshot_file\".into(), Value::String(jsp::basename(&latest.path)));\n                m.insert(\"body\".into(), Value::String(latest.body.clone()));\n                io.out(&format!(\"{}\\n\", json_pretty(&Value::Object(m))));\n            } else {\n                io.out(&latest.body);\n            }\n            0\n        }\n        \"close\" => {\n            let slug_arg = rest.first().map(String::as_str).unwrap_or(\"\");\n            let snapshot_file = rest.get(1).map(String::as_str);\n            let slugs = slug_candidates(rest.first().map(String::as_str), &cwd);\n            let snapshot_file_ok = snapshot_file.map(|s| !s.is_empty()).unwrap_or(false);\n            if slugs.is_empty() || !snapshot_file_ok || rest.len() > 2 {\n                io.err(\"usage: close <resolved-target> <snapshot-file>\\n\");\n                return 1;\n            }\n            let snapshot_file = snapshot_file.unwrap();\n            if jsp::basename(snapshot_file) != snapshot_file\n                || !is_snapshot_name(snapshot_file)\n                || !slugs.iter().any(|slug| snapshot_file.ends_with(&format!(\"__{}.md\", slug)))\n            {\n                return 2;\n            }\n            let snapshot_path = jsp::join(&[&get_critique_dir(&cwd, &env), snapshot_file]);\n            let md = match std::fs::symlink_metadata(&snapshot_path) {\n                Ok(m) => m,\n                Err(_) => return 2,\n            };\n            if !md.is_file() {\n                return 2;\n            }\n            let Some(snapshot) = read_snapshot_at(&snapshot_path) else {","sourceCodeStart":597,"sourceCodeEnd":633,"githubUrl":"https://github.com/pbakaus/impeccable/blob/2bc2879276c1f321a53c4ca99d3371e411329b52/crates/context/src/critique_storage.rs#L597-L633","documentation":"The `close` subcommand requires exactly two arguments — a resolvable slug-or-target and a bare snapshot filename (no path separators, a valid snapshot name ending in `__<slug>.md` for one of the target's slugs). Any violation prints this usage line and exits 1.","triggerScenarios":"Running `close` with fewer than two arguments, more than two arguments, an empty snapshot-file argument, a snapshot file given as a path (e.g. `dir/snap__slug.md`), or a filename whose slug suffix does not match the target's slugs.","commonSituations":"Copy-pasting the full path from the `write` output instead of the basename; accidentally passing frontmatter metadata or flags as extra args; mixing snapshots from a different slug than the given target.","solutions":["Pass the snapshot's basename only, not a path: `close <target> <timestamp>__<slug>.md`.","Provide exactly two arguments, no extras.","Ensure the snapshot filename's `__<slug>.md` suffix matches the first argument's slug (check with `critique-storage slug <target>`).","Verify the slug resolves: an empty/unresolvable first argument also triggers this usage error."],"exampleFix":"// before\nclose ./app.tsx .impeccable/critiques/20260907T120000__apptsx.md\n// after\nclose ./app.tsx 20260907T120000__apptsx.md","handlingStrategy":"validation","validationCode":"const base = path.basename(snapshotFile);\nif (base !== snapshotFile || !/__[^_]+\\.md$/.test(base)) {\n  throw new Error('pass the snapshot basename ending in __<slug>.md, not a path');\n}\nconst extra = args.length - 2;\nif (extra > 0) throw new Error('close takes exactly two arguments');","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always strip directories from the snapshot filename before calling close.","Pass exactly two arguments and no flags.","Confirm the filename slug matches the target via the `slug` subcommand.","Build the filename from the `write` command's stdout basename rather than hand-copying paths."],"tags":["cli","usage","invalid-argument","argument-parsing"],"backgroundTag":"invalid-cli-argument","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"}