{"record":{"id":"2398bf635767a3f4","repo":"Hmbown/CodeWhale","slug":"refusing-to-import-enabled-false-is-a-ha","errorCode":null,"errorMessage":"Refusing to import '{}': {} (enabled=false is a hard block)","messagePattern":"Refusing to import '(.+?)': (.+?) \\(enabled=false is a hard block\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/tui/ui/provider_routes.rs","lineNumber":973,"sourceCode":"    use std::time::{SystemTime, UNIX_EPOCH};\n\n    let home = crate::config::effective_home_dir().unwrap_or_else(|| PathBuf::from(\".\"));\n    let market_path = codewhale_config::codewhale_home()\n        .ok()\n        .map(|h| h.join(\"mcp-marketplace.json\"));\n    let markets: Vec<PathBuf> = market_path.into_iter().collect();\n    let all = discover_external_sources(&home, workspace, &markets);\n    let candidate = all\n        .iter()\n        .find(|c| c.name.eq_ignore_ascii_case(name))\n        .ok_or_else(|| {\n            anyhow::anyhow!(\n                \"No external MCP candidate named '{name}'. Run /mcp import to list sources with provenance.\"\n            )\n        })?;\n\n    if approve && candidate.hard_blocked {\n        anyhow::bail!(\n            \"Refusing to import '{}': {} (enabled=false is a hard block)\",\n            candidate.name,\n            candidate.block_reason.as_deref().unwrap_or(\"hard blocked\")\n        );\n    }\n\n    let mut decisions = HashMap::new();\n    decisions.insert(\n        candidate.name.clone(),\n        if approve {\n            ImportDecision::Approve\n        } else {\n            ImportDecision::Decline\n        },\n    );\n\n    let mut store = load_consent_store(&mcp_import_consent_path());\n    let now = SystemTime::now()","sourceCodeStart":955,"sourceCodeEnd":991,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/crates/tui/src/tui/ui/provider_routes.rs#L955-L991","documentation":"`mcp_import_apply` refuses to approve/import an external MCP server candidate that is marked `hard_blocked` (the source config explicitly sets `enabled=false`). A hard block is a deliberate prohibition from the import source and is never overridable by an approve action, even though the block reason is surfaced in the message.","triggerScenarios":"Running the MCP UI approve/import action (`handle_mcp_ui_action` -> `mcp_import_apply`) with `approve == true` on a candidate whose `candidate.hard_blocked` is true because its source declares `enabled=false`.","commonSituations":"An admin or the upstream MCP source disabled a server (`enabled = false`); a user tries to import it from the /mcp UI and is refused.","solutions":["Set `enabled = true` for that server in the source MCP config that hard-blocked it, then retry the import.","Choose a different import source that does not hard-block the server.","Define the server manually in your own MCP config if you control the trust decision, instead of importing it."],"exampleFix":"// before (source mcp config)\n[my-server]\nenabled = false   // hard block -> import refused\n// after\n[my-server]\nenabled = true","handlingStrategy":"validation","validationCode":"if approve && candidate.hard_blocked { /* disable the approve action for this candidate in the UI */ }","typeGuard":null,"tryCatchPattern":"match mcp_import_apply(...) {\n    Err(e) if e.to_string().contains(\"hard block\") => show_block_reason(&candidate),\n    Err(e) => show_error(e),\n    Ok(_) => {},\n}","preventionTips":["Hide or disable the approve action for hard-blocked MCP candidates in the UI.","Surface candidate.block_reason before prompting for approval."],"tags":["mcp","import","security"],"backgroundTag":"permission-denied","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}