{"record":{"id":"a833403b12109ac2","repo":"Hmbown/CodeWhale","slug":"choose-approve-or-decline","errorCode":null,"errorMessage":"Choose approve or decline","messagePattern":"Choose approve or decline","errorType":"validation","errorClass":"anyhow","httpStatus":null,"severity":"error","filePath":"crates/tui/src/mcp/external_import.rs","lineNumber":667,"sourceCode":"        Ok(ImportPreview {\n            revision,\n            candidates,\n            problems,\n        })\n    })\n}\n\n/// Re-read exact reviewed bytes inside the same config transaction as insertion.\n/// Nothing connects here. Consent follows a successful write and cannot turn a\n/// completed import into a false failed-write receipt.\npub fn apply_reviewed_import(\n    context: &ImportContext<'_>,\n    id: &str,\n    hash: &str,\n    revision: &str,\n    decision: ImportDecision,\n) -> anyhow::Result<ImportReceipt> {\n    anyhow::ensure!(\n        matches!(decision, ImportDecision::Approve | ImportDecision::Decline),\n        \"Choose approve or decline\"\n    );\n    let (candidate, revision) = super::mutate_config(context.mcp_path, Some(revision), |config| {\n        let (candidates, _) = context.discover();\n        let candidate = candidates\n            .into_iter()\n            .find(|candidate| candidate_id(candidate) == id)\n            .ok_or_else(|| {\n                anyhow::anyhow!(\"Reviewed source is unavailable; refresh the import preview\")\n            })?;\n        anyhow::ensure!(\n            candidate.content_hash == hash,\n            \"Source changed; refresh the import preview\"\n        );\n        if decision == ImportDecision::Approve {\n            anyhow::ensure!(\n                !source_blocked(context, &candidate),","sourceCodeStart":649,"sourceCodeEnd":685,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/mcp/external_import.rs#L649-L685","documentation":"`apply_reviewed_import` validates that the supplied `ImportDecision` is exactly Approve or Decline via `anyhow::ensure!`. Any other decision value (other enum variants, i.e. programmatic misuse) is rejected before the config mutation begins.","triggerScenarios":"Calling `apply_reviewed_import` (or the `/mcp import apply` command path through `parse_review_token`/`mcp_import_apply`) with a decision value that is not `ImportDecision::Approve` or `ImportDecision::Decline`.","commonSituations":"A scripted or MCP-driven caller constructing an `ImportDecision` incorrectly; a caller bypassing the token parser and passing a decision parsed from free-form user text.","solutions":["Pass only `ImportDecision::Approve` or `ImportDecision::Decline`.","For CLI/UI use, feed the exact approve/decline command copied from `/mcp import` output instead of hand-building a decision.","Check the parsed review token before calling apply; `parse_review_token` rejects bad tokens earlier with a clearer message."],"exampleFix":"// before\nlet decision = unsafe { std::mem::transmute::<u8, ImportDecision>(raw) };\n// after\nlet decision = match raw {\n    \"approve\" => ImportDecision::Approve,\n    \"decline\" => ImportDecision::Decline,\n    _ => anyhow::bail!(\"decision must be approve or decline\"),\n};","handlingStrategy":"validation","validationCode":"let ok = matches!(decision, ImportDecision::Approve | ImportDecision::Decline);\nif !ok { return Err(anyhow::anyhow!(\"decision must be approve or decline\")); }","typeGuard":"fn is_reviewable(d: &ImportDecision) -> bool {\n    matches!(d, ImportDecision::Approve | ImportDecision::Decline)\n}","tryCatchPattern":"match apply_reviewed_import(...) {\n    Err(e) if e.to_string().contains(\"Choose approve or decline\") => {\n        // fix the decision construction; surface usage help\n    }\n    other => other?,\n}","preventionTips":["Only build ImportDecision through the token parser path","Never cast/transmute enum values from raw input","Validate user-supplied decision strings against a whitelist before constructing the enum"],"tags":["validation","enum","argument"],"backgroundTag":"invalid-enum-value","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T11:17:16.035Z"}