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

  1. Set `enabled = true` for that server in the source MCP config that hard-blocked it, then retry the import.
  2. Choose a different import source that does not hard-block the server.
  3. 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

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


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)