Hmbown/CodeWhale · error

An existing Fleet artifact contains different bytes

Error message

An existing Fleet artifact contains different bytes

What it means

Fleet artifact publication is immutable: when the target file already exists, write re-opens it and compares the existing bytes with the new payload. If they differ, publication fails with this error instead of overwriting — an existing artifact is treated as an immutable published record. Identical re-publication is allowed and returns Ok.

Solutions

  1. Use a content-addressed or run-unique relative path so distinct payloads never collide.
  2. If the new bytes are the correct replacement, this immutability is intentional — remove the stale artifact deliberately and republish, or publish under a new versioned name.
  3. If the existing file was corrupted externally, restore it from the recorded digest/receipt or delete it and republish.
  4. Verify the payload is actually what you intend — the mismatch may reveal a non-deterministic generation step upstream.

Example fix

// before
artifacts::write(ws, Path::new("report.txt"), &new_bytes)?;
// after
let path = format!("report-{}.txt", sha256_hex(&new_bytes));
artifacts::write(ws, Path::new(&path), &new_bytes)?;
Defensive patterns

Strategy: validation

Validate before calling

let path = format!("artifacts/{}-{}", run_id, file_name);
if ws.join(&path).exists() {
    // treat as immutable: publish under a new name or compare first
}

Try / catch

match artifacts::write(ws, &path, &bytes) {
    Err(e) if e.to_string().contains("different bytes") => {
        eprintln!("artifact {} already published with other content; use a new path", path);
    }
    r => r?,
}

Prevention

When it happens

Trigger: Calling artifacts::write with a relative path that already exists in the Fleet workspace but whose on-disk content differs from the bytes being written (io::ErrorKind::AlreadyExists from publish, then byte comparison fails).

Common situations: Two runs writing different content to the same deterministic artifact path; a retry reusing a path after the payload changed (e.g. regenerated report with new data); manual editing or corruption of a previously published artifact; a stale artifact left from an earlier version of the pipeline.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/b678c5dd3ea006a7. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/fleet/artifacts.rs:36

// without retaining all bytes. The writer shares the ceiling so it cannot
// publish an artifact the evidence reader is unable to verify.
const MAX_ARTIFACT_BYTES: u64 = 16 * 1024 * 1024;

pub(crate) fn write(workspace: &Path, relative: &Path, bytes: &[u8]) -> Result<()> {
    ensure!(
        bytes.len() as u64 <= MAX_ARTIFACT_BYTES,
        "Fleet artifact exceeds the 16 MiB limit"
    );
    let parent = WorkspaceFile::open(workspace, relative, true)?;
    match parent.publish(bytes) {
        Ok(()) => Ok(()),
        Err(error) if error.kind() == io::ErrorKind::AlreadyExists => {
            let existing = parent.open_file()?;
            let mut saved = Vec::new();
            existing
                .take(bytes.len() as u64 + 1)
                .read_to_end(&mut saved)?;
            ensure!(
                saved == bytes,
                "An existing Fleet artifact contains different bytes"
            );
            Ok(())
        }
        Err(error) => Err(error).context("Publishing Fleet artifact"),
    }
}

pub(crate) fn read_verified(
    workspace: &Path,
    artifact: &FleetArtifactRef,
    preview_limit: u64,
) -> Result<(Vec<u8>, u64)> {
    let parent = WorkspaceFile::open(workspace, &artifact.path, false)?;
    let file = parent.open_file()?;
    let size = file.metadata()?.len();
    ensure!(

View on GitHub (pinned to 73e0f67d83)