Hmbown/CodeWhale · error · anyhow::Error

destination {} already exists with different content

Error message

destination {} already exists with different content

What it means

Raised in import_external when the destination directory already exists but its computed package digest differs from the expected digest supplied by the caller. This is a conflict guard: the existing owned skill is not byte-identical to the package being imported, and the current conflict policy does not authorize overwriting it.

Source

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

        ),
    };

    let dest_exists = validate_owned_child(&skills_dir, &dest, false)?;
    if dest_exists {
        let existing = package_digest::compute_package_digest(&dest).ok();
        if existing.as_deref() == Some(expected_digest.as_str()) {
            return Ok(SkillMutationReceipt {
                action: SkillActionKind::Import,
                name: source_id.canonical_name.clone(),
                scope: target.as_skill_scope(),
                safe_target_path: safe_display_path(&dest, Some(ctx.workspace), ctx.home),
                before_digest: before,
                after_digest: existing,
                outcome: SkillMutationOutcome::AlreadyPresent,
            });
        }
        if conflict_policy == ConflictPolicy::Reject {
            bail!(
                "destination {} already exists with different content",
                dest.display()
            );
        }
    }

    // Re-verify source digest immediately before copy (TOCTOU).
    let _ = verify_expected_digest(&source_path, Some(&expected_digest))?;
    validate_owned_target_chain(anchor, &skills_dir, true)?;

    let staging = skills_dir.join(format!("{dest_segment}.tmp"));
    if validate_owned_child(&skills_dir, &staging, false)? {
        fs::remove_dir_all(&staging)
            .with_context(|| format!("failed to clean stale staging dir {}", staging.display()))?;
    }
    copy_skill_package(&source_path, &staging)?;
    validate_owned_target_chain(anchor, &skills_dir, true)?;
    validate_owned_child(&skills_dir, &staging, true)?;

View on GitHub (pinned to 0c42157ee5)

Solutions

  1. Choose a conflict policy that allows replacing (which backs up the existing skill first)
  2. Remove the existing destination skill and retry the import
  3. Verify the expected digest passed in matches the package you actually want; a stale digest causes a spurious conflict
Defensive patterns

Strategy: validation

When it happens

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