Hmbown/CodeWhale · error · anyhow
Source is disabled or its workspace is untrusted
Error message
Source is disabled or its workspace is untrusted
What it means
On approval, codewhale re-checks `source_blocked(context, &candidate)` just before committing. If the source is disabled or its workspace is not trusted at apply time, the import is refused — the preview-time trust state is re-verified to avoid importing from a source that became untrusted.
Solutions
- Trust the workspace the source lives in (respond to the trust prompt or add it to trusted workspaces), then re-apply.
- Re-enable the disabled source if it should be imported.
- Re-run `/mcp import` to regenerate a preview that reflects the current trust/disabled state.
Example fix
// before (untrusted workspace) codewhale mcp import approve <token> // after codewhale workspace trust /path/to/project codewhale mcp import approve <token>
Defensive patterns
Strategy: validation
Validate before calling
let (candidates, _) = context.discover();
if let Some(c) = candidates.iter().find(|c| candidate_id(c) == id) {
if source_blocked(&context, c) {
eprintln!("source is blocked: enable it or trust the workspace first");
}
} Try / catch
match apply_reviewed_import(...) {
Err(e) if e.to_string().contains("disabled or its workspace is untrusted") => {
// trust the workspace / re-enable source, then retry
}
other => other?,
} Prevention
- Trust project workspaces before generating import previews
- Check source enabled state before approving
- Review workspace trust settings when source files move between projects
When it happens
Trigger: Approving an import where, at apply time, the candidate's source is marked disabled in the merged view, or the workspace containing the source file is not in the trusted-workspace set (e.g. trust was revoked or the file moved to an untrusted directory).
Common situations: User declined a workspace-trust prompt earlier; the source config lives in a new project directory that has not been marked trusted; an admin policy disabled the source after the preview.
Understand the failure class
Background: "You do not have permission" / 403 Forbidden errors: authenticated but not allowed — causes and fixes across open-source libraries — this error's family across 31 libraries.
Related errors
- append_allow_rules only accepts action = "allow"
- Codewhale credentials directory has an unsupported component
- Codewhale terminal receipt exceeded its string bound
- CodewhalePet/1
- Failed to update setting: invalid permission posture
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/17a5647d825c78ab.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/mcp/external_import.rs:684
) -> 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),
"Source is disabled or its workspace is untrusted"
);
anyhow::ensure!(
!context.merged()?.servers.contains_key(&candidate.name)
&& !config.servers.contains_key(&candidate.name),
"A managed, project or plugin connector already uses this name"
);
let mut server = candidate.server.clone();
server.enabled = false;
server.disabled = true;
config.servers.insert(candidate.name.clone(), server);
}
Ok(candidate)
})?;
let decisions = HashMap::from([(candidate.name.clone(), decision)]);
let now = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)View on GitHub (pinned to 73e0f67d83)