Hmbown/CodeWhale · error
Refusing to import ' ': (enabled=false is a hard block)
Error message
Refusing to import '{}': {} (enabled=false is a hard block) What it means
`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.
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.
Example fix
// before (source mcp config) [my-server] enabled = false // hard block -> import refused // after [my-server] enabled = true
Defensive patterns
Strategy: validation
Validate before calling
if approve && candidate.hard_blocked { /* disable the approve action for this candidate in the UI */ } Try / catch
match mcp_import_apply(...) {
Err(e) if e.to_string().contains("hard block") => show_block_reason(&candidate),
Err(e) => show_error(e),
Ok(_) => {},
} Prevention
- Hide or disable the approve action for hard-blocked MCP candidates in the UI.
- Surface candidate.block_reason before prompting for approval.
When it happens
Trigger: 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`.
Common situations: 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.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- A managed, project or plugin connector already uses this…
- Invalid MCP command
- Invalid MCP entry; contents omitted
- legacy import refused: symlink or size bound
- MCP config path cannot contain '..' components
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/2398bf635767a3f4.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/tui/ui/provider_routes.rs:973
use std::time::{SystemTime, UNIX_EPOCH};
let home = crate::config::effective_home_dir().unwrap_or_else(|| PathBuf::from("."));
let market_path = codewhale_config::codewhale_home()
.ok()
.map(|h| h.join("mcp-marketplace.json"));
let markets: Vec<PathBuf> = market_path.into_iter().collect();
let all = discover_external_sources(&home, workspace, &markets);
let candidate = all
.iter()
.find(|c| c.name.eq_ignore_ascii_case(name))
.ok_or_else(|| {
anyhow::anyhow!(
"No external MCP candidate named '{name}'. Run /mcp import to list sources with provenance."
)
})?;
if approve && candidate.hard_blocked {
anyhow::bail!(
"Refusing to import '{}': {} (enabled=false is a hard block)",
candidate.name,
candidate.block_reason.as_deref().unwrap_or("hard blocked")
);
}
let mut decisions = HashMap::new();
decisions.insert(
candidate.name.clone(),
if approve {
ImportDecision::Approve
} else {
ImportDecision::Decline
},
);
let mut store = load_consent_store(&mcp_import_consent_path());
let now = SystemTime::now()View on GitHub (pinned to 433685b202)