astrid-runtime/astrid · error
InvalidInput
InvalidInput
Error message
staged executable is not on the live executable volume
What it means
An executable replacement requires the staged (temporary) file to live on the same NTFS volume as the live install directory so the final swap can be atomic. prepare_executable_transaction compares volume_root(staged) with the install volume and rejects with InvalidInput when they differ. No files are modified when this fires.
Source
Thrown at crates/astrid-core/src/platform_fs/windows/executable.rs:223
for name in names {
let source = extract_dir.join(name);
extract_guard.verify()?;
install_guard.verify()?;
let staged_name = format!(".{name}.{transaction_id}.new");
let (temporary, new_hash) = stage_transaction_copy_authenticated(
install_guard,
extract_guard,
FileContract::Trusted,
BoundaryContract::TrustedForCreate,
install_dir,
&source,
&staged_name,
)?;
cleanup.track(temporary.clone());
#[cfg(test)]
test_maybe_fail_preparation(journal.entries.len())?;
if volume_root(&temporary)? != install_volume {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
"staged executable is not on the live executable volume",
));
}
let live = install_dir.join(name);
let had_live = guarded_file_exists(install_guard, &live)?;
let (rollback, old_hash) = if had_live {
let rollback_name = format!(".{name}.{transaction_id}.rollback");
let (rollback_path, old_hash) = stage_transaction_copy_authenticated(
install_guard,
install_guard,
FileContract::Trusted,
BoundaryContract::TrustedForCreate,
install_dir,
&live,
&rollback_name,
)?;
cleanup.track(rollback_path);View on GitHub (pinned to affd8760f4)
Solutions
- Configure the staging/temp location to be on the same volume as the install directory
- Verify the install directory is not behind a junction/subst/mapped path that changes its volume root
- Canónico the paths (canonicalize) before the call so volume_root computes the intended volume
- If cross-volume installs are unavoidable, copy staged bytes into a temporary file on the install volume first
Example fix
// before: staging in %TEMP% on D: while installing to C:\Program Files\App
let staged = temp_dir().join("staged.exe");
// after: stage inside the install volume
let staged = install_dir.join(".staging").join("staged.exe"); Defensive patterns
Strategy: validation
Validate before calling
// Confirm staging and install paths share a volume before the call
fn same_volume(a: &std::path::Path, b: &std::path::Path) -> bool {
use std::os::windows::ffi::OsStrExt;
// compare volume root components of canonicalized a and b
a.canonicalize().ok().zip(b.canonicalize().ok())
.map(|(a, b)| {
let av: String = a.components().take(1).map(|c| c.as_os_str().to_string_lossy().into_owned()).collect();
let bv: String = b.components().take(1).map(|c| c.as_os_str().to_string_lossy().into_owned()).collect();
av.eq_ignore_ascii_case(&bv)
}).unwrap_or(false)
} Try / catch
if !same_volume(&staged, &install_dir) {
// stage on the install volume first, then call replace_executable_set
} Prevention
- Keep staging/temp on the same drive as the install directory
- Canonicalize junctions/mapped paths before computing volume roots
- Mount install and temp directories on the same volume in CI/containers
When it happens
Trigger: Calling replace_executable_set with a staged/temporary path or install directory configuration where the staging location resolves to a different volume than the live executable directory (e.g. staging on a temp drive, install on C:).
Common situations: TEMP on a different drive from Program Files; mapped or junctioned install paths whose volume_root differs; container or CI setups mounting install and temp on separate volumes; users relocating the install directory without updating staging config.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- InvalidData
- AlreadyExists
- mountpoint is not valid UTF-16
- WinFsp mountpoint is not valid UTF-16
- PermissionDenied
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/a61998c0dbb770b3.
Report an issue: GitHub.