Hmbown/CodeWhale · error · anyhow::Error
only CodeWhale managed skills can be trusted
Error message
only CodeWhale managed skills can be trusted
What it means
Thrown by trust_skill in the skill-mutation API when asked to write a trust receipt (trust v2) for a skill whose source_kind is not SkillSourceKind::CodeWhaleManaged. Trust receipts pin a content digest and are only meaningful for skills installed and owned by CodeWhale roots; third-party, vendored, or user-imported skills are rejected so their trust state cannot be silently rewritten. The check runs after the writable-owned root check, so the skill is on a CodeWhale root but was not placed there by the managed installer.
Source
Thrown at crates/tui/src/skills/mutation.rs:978
scope,
safe_target_path: safe_display_path(&path, Some(ctx.workspace), ctx.home),
before_digest: before,
after_digest: None,
outcome: SkillMutationOutcome::Removed,
})
}
fn trust_skill(
skill_id: AuditedSkillId,
expected_digest: String,
ctx: &MutationContext<'_>,
) -> Result<SkillMutationReceipt> {
let (skill, path) = find_audited_skill(ctx, &skill_id)?;
if !skill.root.is_writable_owned() {
bail!("refusing to trust skill outside CodeWhale-owned roots");
}
if skill.source_kind != SkillSourceKind::CodeWhaleManaged {
bail!("only CodeWhale managed skills can be trusted");
}
validate_owned_skill_path(ctx, &skill, &path)?;
let before = verify_expected_digest(&path, Some(&expected_digest))?;
validate_owned_skill_path(ctx, &skill, &path)?;
write_trust_v2(&path, &expected_digest)?;
let scope = match skill.root.kind {
SkillRootKind::CodeWhaleProject => SkillScope::Project,
SkillRootKind::CodeWhaleGlobal => SkillScope::Global,
_ => SkillScope::Logical,
};
Ok(SkillMutationReceipt {
action: SkillActionKind::Trust,
name: skill_id.canonical_name,
scope,
safe_target_path: safe_display_path(&path, Some(ctx.workspace), ctx.home),
before_digest: before.clone(),
after_digest: before,
outcome: SkillMutationOutcome::Trusted,View on GitHub (pinned to 0c42157ee5)
Solutions
- Reinstall the skill through CodeWhale's managed skill install path so it is recorded as CodeWhaleManaged, then retry the trust mutation.
- Verify what you are trusting first: list audited skills with their source_kind and skip non-managed ones instead of trusting all ids blindly.
- If the skill content is correct and you want it managed, remove the manually placed copy and install it via the managed installer rather than editing trust state by hand.
Example fix
// before
for skill in audited_skills {
trust_skill(skill.id, skill.digest, &ctx)?; // bails on non-managed skills
}
// after
for skill in audited_skills {
if skill.source_kind == SkillSourceKind::CodeWhaleManaged {
trust_skill(skill.id, skill.digest, &ctx)?;
}
} Defensive patterns
Strategy: validation
Validate before calling
use codewhale_tui::skills::{audit_skills, SkillSourceKind};
fn is_trustable(ctx: &MutationContext<'_>, skill_id: &AuditedSkillId) -> bool {
match find_audited_skill(ctx, skill_id) {
Ok((skill, _)) => skill.source_kind == SkillSourceKind::CodeWhaleManaged
&& skill.root.is_writable_owned(),
Err(_) => false,
}
} Prevention
- Filter audited skills by source_kind == CodeWhaleManaged before batch trust operations.
- Install skills through the managed installer instead of copying directories into CodeWhale roots.
- Treat backup/dotfile-synced skill directories as unmanaged: reinstall before trusting.
When it happens
Trigger: Calling the trust mutation with a skill id that resolves to a skill copied manually into a CodeWhale root, synced from another machine, or registered through a non-managed source; any trust request where find_audited_skill returns a record with source_kind != CodeWhaleManaged.
Common situations: Re-registering skills after restoring a backup or dotfile sync into ~/.codewhale or .codewhale/skills; hand-editing skill directories; migrating skills between projects; scripts that trust every audited skill in a loop without filtering by source.
Related errors
- persistent allow rules must be scoped to a workspace
- persistent command allow rules must use exact matching
- persistent allow rules must match an exact command or path
- persistent command allow rules must not be empty
- persistent path allow rules must stay within the workspace
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/7dc31545ee1941d7.
Report an issue: GitHub.