astrid-runtime/astrid · error

AlreadyExists

AlreadyExists

Error message

could not allocate a unique private staging path

What it means

stage_unique_bytes_with_share tries up to 16 times to create a fresh private temp file named `.{label}.{uuid}.tmp` in the parent directory. If every attempt collides with an existing file (create_guarded_private_file_with_share returns AlreadyExists), it gives up with this AlreadyExists error. With UUID names this almost never happens naturally, so it usually signals something pathologically wrong with the parent directory or name generation.

Source

Thrown at crates/astrid-core/src/platform_fs/windows/io.rs:350

            validate_private_acl_handle(
                output.as_raw_handle().cast(),
                false,
                &temporary.display().to_string(),
            )
        })();
        if let Err(error) = write_result {
            drop(output);
            let _ = remove_guarded_file(guard, &temporary);
            return Err(error);
        }
        if let Err(error) = guard.verify() {
            drop(output);
            let _ = remove_guarded_file(guard, &temporary);
            return Err(error);
        }
        return Ok((temporary, output));
    }
    Err(io::Error::new(
        io::ErrorKind::AlreadyExists,
        "could not allocate a unique private staging path",
    ))
}

pub(super) fn replace_file_checked(
    guard: &TrustedPathGuard,
    live: &Path,
    replacement: &Path,
) -> io::Result<()> {
    #[cfg(test)]
    if let Some(result) = test_rename_fault() {
        return result;
    }
    rename_guarded_file(guard, replacement, live, true).map_err(|error| {
        with_context(
            error,
            format!(

View on GitHub (pinned to affd8760f4)

Solutions

  1. Delete orphaned `.{label}.*.tmp` files in the staging/parent directory and retry.
  2. Investigate antivirus/security filter drivers that may be interfering with file creation; add exclusions for the staging directory.
  3. Check filesystem health and permissions on the parent directory (it must be writable and support exclusive creation).
  4. Upgrade/report to the library maintainers if it persists — 16 UUID collisions in a row indicates an environment bug, not a name-space issue.

Example fix

// before: leaving failed temp files behind forever
let tmp = stage_unique_bytes(&guard, &parent, &bytes, "payload")?; // 16 collisions -> AlreadyExists
// after: clean stale temp files first
for entry in fs::read_dir(&parent)? {
    let p = entry?.path();
    if p.file_name().map_or(false, |n| n.to_string_lossy().starts_with(".payload."))
        && p.extension().map_or(false, |e| e == "tmp")
    {
        let _ = fs::remove_file(&p);
    }
}
let tmp = stage_unique_bytes(&guard, &parent, &bytes, "payload")?;
Defensive patterns

Strategy: validation

Validate before calling

// Rust: ensure the parent dir is writable and free of stale temp files before staging
let probe = parent.join(".write_probe");
fs::File::create(&probe)?;
fs::remove_file(&probe)?;
for entry in fs::read_dir(&parent)? {
    let p = entry?.path();
    if let Some(n) = p.file_name().and_then(|n| n.to_str()) {
        if n.starts_with(&format!(".{label}.")) && n.ends_with(".tmp") {
            let _ = fs::remove_file(&p); // clear collision space
        }
    }
}

Try / catch

// Rust
match stage_unique_bytes(&guard, &parent, &bytes, "payload") {
    Ok(path) => use(path),
    Err(e) if e.kind() == io::ErrorKind::AlreadyExists
        && e.to_string().contains("unique private staging path") => {
        clean_stale_temp_files(&parent, "payload");
        stage_unique_bytes(&guard, &parent, &bytes, "payload") // one retry
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Called via stage_unique_bytes / stage_unique_bytes_retained; raised only after all 16 create attempts fail with AlreadyExists. Possible with an extremely large number of leftover `.label.*.tmp` files, a filesystem/plugin that reports AlreadyExists for unrelated failures (e.g. antivirus blocking creation), or a guarded-path verification problem surfacing as a collision.

Common situations: Accumulated orphaned temp files from thousands of interrupted runs filling the collision space; a broken security product returning spurious ERROR_ALREADY_EXISTS on every create; a read-only or misconfigured parent directory whose error is misreported by a filter driver.

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 astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/49cc9f6cd957cb5c. Report an issue: GitHub.