Hmbown/CodeWhale · error · anyhow::Error

imported content digest mismatch after copy; aborted

Error message

imported content digest mismatch after copy; aborted

What it means

Raised during import finalization: after copying the staged package into the destination, the freshly written content's digest does not match the expected digest that was verified before the copy. This indicates the on-disk result diverged from the audited source (concurrent modification, filesystem issue, or a non-deterministic copy), and the import is aborted rather than finalized with unverified content.

Source

Thrown at crates/tui/src/skills/mutation.rs:777

            return Err(err).context("failed to replace destination with imported skill");
        }
        backup_path = Some(backup);
    } else if let Err(err) = fs::rename(&staging, &dest) {
        let _ = fs::remove_dir_all(&staging);
        return Err(err).context("failed to install imported skill");
    }
    validate_owned_target_chain(anchor, &skills_dir, true)?;
    validate_owned_child(&skills_dir, &dest, true)?;

    // Keep backup until digest + marker finalize succeed so a failed import
    // can restore the previous owned skill.
    let finalize = (|| -> Result<String> {
        let _ = verify_expected_digest(&source_path, Some(&expected_digest))?;
        validate_owned_target_chain(anchor, &skills_dir, true)?;
        validate_owned_child(&skills_dir, &dest, true)?;
        let after = package_digest::compute_package_digest(&dest)?;
        if after != expected_digest {
            bail!("imported content digest mismatch after copy; aborted");
        }
        write_installed_from_v2(
            &dest,
            &format!("import:{}", source_skill.safe_display_path),
            None,
            &expected_digest,
            &after,
            &source_id.canonical_name,
        )?;
        Ok(after)
    })();

    let after = match finalize {
        Ok(after) => {
            if let Some(backup) = backup_path.take() {
                fs::remove_dir_all(&backup).ok();
            }
            after

View on GitHub (pinned to 0c42157ee5)

Solutions

  1. Re-scan the external skill source to obtain a fresh digest and retry the import
  2. Check whether the source package was modified concurrently during the import
  3. If a backup of the previous owned skill was kept, it is restored; verify the destination state after the failure
Defensive patterns

Strategy: retry

When it happens

Trigger: Thrown at crates/tui/src/skills/mutation.rs:777 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/52a3c39d96f49c9b. Report an issue: GitHub.