Hmbown/CodeWhale · error · anyhow

Choose approve or decline

Error message

Choose approve or decline

What it means

`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.

Solutions

  1. Pass only `ImportDecision::Approve` or `ImportDecision::Decline`.
  2. For CLI/UI use, feed the exact approve/decline command copied from `/mcp import` output instead of hand-building a decision.
  3. Check the parsed review token before calling apply; `parse_review_token` rejects bad tokens earlier with a clearer message.

Example fix

// before
let decision = unsafe { std::mem::transmute::<u8, ImportDecision>(raw) };
// after
let decision = match raw {
    "approve" => ImportDecision::Approve,
    "decline" => ImportDecision::Decline,
    _ => anyhow::bail!("decision must be approve or decline"),
};
Defensive patterns

Strategy: validation

Validate before calling

let ok = matches!(decision, ImportDecision::Approve | ImportDecision::Decline);
if !ok { return Err(anyhow::anyhow!("decision must be approve or decline")); }

Type guard

fn is_reviewable(d: &ImportDecision) -> bool {
    matches!(d, ImportDecision::Approve | ImportDecision::Decline)
}

Try / catch

match apply_reviewed_import(...) {
    Err(e) if e.to_string().contains("Choose approve or decline") => {
        // fix the decision construction; surface usage help
    }
    other => other?,
}

Prevention

When it happens

Trigger: 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`.

Common situations: 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.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/a833403b12109ac2. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/mcp/external_import.rs:667

        Ok(ImportPreview {
            revision,
            candidates,
            problems,
        })
    })
}

/// Re-read exact reviewed bytes inside the same config transaction as insertion.
/// Nothing connects here. Consent follows a successful write and cannot turn a
/// completed import into a false failed-write receipt.
pub fn apply_reviewed_import(
    context: &ImportContext<'_>,
    id: &str,
    hash: &str,
    revision: &str,
    decision: ImportDecision,
) -> anyhow::Result<ImportReceipt> {
    anyhow::ensure!(
        matches!(decision, ImportDecision::Approve | ImportDecision::Decline),
        "Choose approve or decline"
    );
    let (candidate, revision) = super::mutate_config(context.mcp_path, Some(revision), |config| {
        let (candidates, _) = context.discover();
        let candidate = candidates
            .into_iter()
            .find(|candidate| candidate_id(candidate) == id)
            .ok_or_else(|| {
                anyhow::anyhow!("Reviewed source is unavailable; refresh the import preview")
            })?;
        anyhow::ensure!(
            candidate.content_hash == hash,
            "Source changed; refresh the import preview"
        );
        if decision == ImportDecision::Approve {
            anyhow::ensure!(
                !source_blocked(context, &candidate),

View on GitHub (pinned to 73e0f67d83)