Hmbown/CodeWhale · error · anyhow::Error
skill content changed since audit (expected {expected}, foun
Error message
skill content changed since audit (expected {expected}, found {current}); re-review before mutating What it means
verify_expected_digest recomputes the package digest and compares it to the digest recorded at audit time (or supplied by the caller). This bail fires on mismatch: the skill's files changed on disk after the user reviewed them, so proceeding could execute unreviewed content. The modified skill package is the input at fault; this is a TOCTOU/consistency guard used by import, update, remove, and trust.
Source
Thrown at crates/tui/src/skills/mutation.rs:561
_ => None,
}
.filter(|name| !name.is_empty())
.ok_or_else(|| {
anyhow::anyhow!(
"invalid on-disk package directory for skill '{}'",
skill_id.canonical_name
)
})?;
Ok(name)
}
fn verify_expected_digest(path: &Path, expected: Option<&str>) -> Result<Option<String>> {
let current = package_digest::compute_package_digest(path)
.with_context(|| format!("cannot digest {}", path.display()))?;
if let Some(expected) = expected
&& expected != current
{
bail!(
"skill content changed since audit (expected {expected}, found {current}); \
re-review before mutating"
);
}
Ok(Some(current))
}
fn ensure_remote_updatable(skill_dir: &Path) -> Result<()> {
let marker_path = skill_dir.join(install::INSTALLED_FROM_MARKER);
let body = fs::read_to_string(&marker_path)
.with_context(|| format!("failed to read {}", marker_path.display()))?;
let value: serde_json::Value = serde_json::from_str(&body)
.with_context(|| format!("malformed {}", install::INSTALLED_FROM_MARKER))?;
let spec = value
.get("spec")
.and_then(|v| v.as_str())
.unwrap_or_default();
if !install::is_registry_updatable_spec(spec) {View on GitHub (pinned to 0c42157ee5)
Solutions
- Re-review the skill contents (the review gate) and retry the mutation with the fresh digest
- Restore the package to its audited state before mutating
- Re-run the skills scan to pick up the new digest as the audit baseline
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at crates/tui/src/skills/mutation.rs:561 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/95be4c86e86d16b4.
Report an issue: GitHub.