{"record":{"id":"1ba7d4caabe09bcf","repo":"nikivdev/code","slug":"review-todo-id-is-ambiguous","errorCode":null,"errorMessage":"Review todo id '{}' is ambiguous","messagePattern":"Review todo id '(.+?)' is ambiguous","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/reviews_todo.rs","lineNumber":149,"sourceCode":"                .as_deref()\n                .map(|r| r.starts_with(\"flow-review-issue-\"))\n                .unwrap_or(false)\n        })\n        .map(|(i, _)| i)\n        .collect();\n\n    // Match by id prefix among review items\n    let mut matches = Vec::new();\n    for &idx in &review_indices {\n        if items[idx].id == id || items[idx].id.starts_with(id) {\n            matches.push(idx);\n        }\n    }\n\n    let idx = match matches.len() {\n        0 => bail!(\"Review todo '{}' not found\", id),\n        1 => matches[0],\n        _ => bail!(\"Review todo id '{}' is ambiguous\", id),\n    };\n\n    if items[idx].status == \"completed\" {\n        println!(\"Already completed: {}\", items[idx].id);\n        return Ok(());\n    }\n\n    items[idx].status = \"completed\".to_string();\n    items[idx].updated_at = Some(Utc::now().to_rfc3339());\n    todo::save_items(&path, &items)?;\n    println!(\"✓ {} -> completed\", items[idx].id);\n\n    Ok(())\n}\n\nfn fix_review_todos(id: Option<&str>, all: bool) -> Result<()> {\n    let root = todo::project_root();\n    let items = todo::load_review_todos(&root)?;","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/reviews_todo.rs#L131-L167","documentation":"Raised when a review todo operation receives an id that matches multiple review todo entries, so the target cannot be uniquely resolved.","triggerScenarios":"Calling done with a short id prefix such as \"a\" when two todos start with \"a\".","commonSituations":"Copy-pasting only the first character of an id; shortened ids colliding after many todos accumulate; tab-completion not used.","solutions":["Supply more characters of the id until it is unique","Use the full todo id","List todos first and pick the exact id"],"exampleFix":"// before\ndone_review_todo(root, \"a\")  // matches a1... and a2...\n// after\ndone_review_todo(root, \"a1f3c9de\")","handlingStrategy":"validation","validationCode":"let ids: Vec<String> = list_review_todos(root)?.iter().map(|t| t.id.clone()).collect();\nlet n = ids.iter().filter(|i| i.starts_with(prefix)).count();\nif n != 1 { eprintln!(\"prefix {prefix} matches {n} todos; use a longer prefix\"); return; }","typeGuard":null,"tryCatchPattern":"match done_review_todo(root, prefix) {\n    Err(e) if e.to_string().contains(\"ambiguous\") => eprintln!(\"lengthen the id prefix\"),\n    other => other?,\n}","preventionTips":["Use full todo ids when scripting","Take advantage of shell tab-completion against the id list","Regenerate the list and re-check uniqueness before each batch operation"],"tags":["cli","lookup","ambiguity"],"backgroundTag":"ambiguous-identifier","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}