{"record":{"id":"cef4c4eba828acec","repo":"Hmbown/CodeWhale","slug":"no-external-mcp-candidate-named-name-run-mcp","errorCode":null,"errorMessage":"No external MCP candidate named '{name}'. Run /mcp import to list sources with provenance.","messagePattern":"No external MCP candidate named '(.+?)'\\. Run /mcp import to list sources with provenance\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/tui/ui/provider_routes.rs","lineNumber":967,"sourceCode":") -> anyhow::Result<String> {\n    use crate::mcp::external_import::{\n        ImportDecision, apply_approved, discover_external_sources, load_consent_store,\n        merge_approved_into_config, record_decisions, save_consent_store,\n    };\n    use std::collections::HashMap;\n    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 {","sourceCodeStart":949,"sourceCodeEnd":985,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/crates/tui/src/tui/ui/provider_routes.rs#L949-L985","documentation":"Thrown by mcp_import_apply when the named external MCP candidate cannot be found among the sources discovered by discover_external_sources (home dir, workspace, and market paths). Import works only on candidates the discovery pass enumerated, so an unknown name is rejected with a pointer to /mcp import for a provenance listing. Case-insensitive match is used but the name must still exist.","triggerScenarios":"Calling the apply/import UI action with a name never produced by discovery; discovery ran before a new market file was added; name casing differs beyond ASCII case-fold.","commonSituations":"User typed a server name from memory instead of the /mcp import listing; external source file moved or renamed; marketplace path not configured so discovery never saw the candidate.","solutions":["Run /mcp import to list candidate names with provenance and copy the exact name","Check that the source file (e.g. claude desktop config, marketplace JSON) is in a scanned path","Re-run import discovery after adding or fixing market paths in config"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"let candidates = discover_external_sources(&home, &workspace, &markets);\nif !candidates.iter().any(|c| c.name.eq_ignore_ascii_case(name)) { return Err(anyhow!(\"no candidate '{name}'\")); }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always derive import names from /mcp import output, never from memory","Keep market paths configured before importing","Refresh discovery after editing external source files"],"tags":["mcp","import","discovery"],"backgroundTag":"entity-not-found","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"}