pbakaus/impeccable · error
ambiguous snapshot slug; use an explicit ./path or remove th
Error message
ambiguous snapshot slug; use an explicit ./path or remove the local name collision
What it means
`latest` refuses to answer when the argument is a short 'ready slug' while a local path of that name also exists on disk, and the newest snapshot's recorded target identity does not match the local target's identity — the slug is ambiguous, so the command prints this message and exits 2 without closing or returning a possibly-wrong snapshot.
Source
Thrown at crates/context/src/critique_storage.rs:573
else {
return 2;
};
let mut latest =
read_newest_snapshot_for_identity_slugs(&slugs, target_identity.as_deref(), &cwd, &env);
if latest.is_none() && !ready_slug {
// Identity-less snapshots are safe only under the new/current
// collision-resistant slug. A pre-hash slug suffix alone cannot
// prove which long target owned the historical snapshot.
latest = slugs.first().and_then(|slug| read_newest_snapshot_for_identity(slug, None, &cwd, &env));
}
let latest = latest.unwrap_or(newest_for_slug);
if meta_closed(&latest) {
return 2;
}
let recorded_target_identity = snapshot_target_identity(&latest);
let matching_identity = recorded_target_identity == target_identity;
if ready_slug && target_path.as_deref().map(exists).unwrap_or(false) && !matching_identity {
io.err("ambiguous snapshot slug; use an explicit ./path or remove the local name collision\n");
return 2;
}
let concrete_target = !ready_slug || matching_identity;
if concrete_target && recorded_target_identity.is_some() && !matching_identity {
return 2;
}
let concrete_local_target = concrete_target && target_path.is_some();
if concrete_local_target {
let recorded_fp = match latest.meta.get("target_fingerprint") {
Some(Value::String(s)) => Some(s.clone()),
_ => None,
};
// JS strict `!==`: equal only when both are the same string;
// undefined/null on either side always differ.
let differ = !matches!((&recorded_fp, &target_fingerprint), (Some(a), Some(b)) if a == b);
if differ {
return match close_snapshot(&latest.path, &cwd, &env) {
Err(e) => {View on GitHub (pinned to 2bc2879276)
Solutions
- Disambiguate by passing the explicit local path with `./` prefix: `latest ./mypage`.
- Remove or rename the local file that collides with the snapshot slug.
- If the local target is the one you mean, recreate/overwrite the snapshot via `write` so its recorded identity matches.
- Use the fully resolved path form of the target instead of the short slug.
Example fix
// before latest mypage // ambiguous: local ./mypage exists with different identity // after latest ./mypage
Defensive patterns
Strategy: validation
Validate before calling
const localName = target.replace(/^\.\//, '');
if (!target.startsWith('./') && fs.existsSync(localName)) {
target = './' + localName; // disambiguate short slug from local file
} Prevention
- Prefer explicit `./path` targets over short slugs when a same-named local file may exist.
- Re-snapshot a target after recreating it so identities match.
- Keep one project per working directory to avoid slug collisions.
- Treat exit code 2 as 'no usable snapshot' and write a fresh one.
When it happens
Trigger: Calling `critique-storage latest mypage` when both a snapshot for slug `mypage` exists AND a file/directory named `mypage` exists in the cwd, and the snapshot was recorded against a different target identity (e.g. the local `mypage` was recreated or points elsewhere).
Common situations: A target file was deleted and recreated under the same short name, the cwd changed so a same-named local file now shadows the slug, or snapshots exist from an older project sharing the slug.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- no stable slug for input
- {}
- concept-seed: --candidate-count must be an integer from 5 to
- Unknown ignore-rule flag: ${arg}
- Pass a rule id, e.g. ${IMPECCABLE_COMMAND} hooks ignore-rule
AI-assisted analysis of pbakaus/impeccable@2bc2879276 (2026-09-08).
Data as JSON: /api/errors/ee9236698393cd5d.
Report an issue: GitHub.