astrid-runtime/astrid · error · io::Error
capability-relative exclusive rename is unsupported
Error message
capability-relative exclusive rename is unsupported
What it means
rename_no_replace performs an exclusive (no-replace) rename relative to two capability directories. On platforms/APIs lacking a no-replace rename (e.g. no renameat2 with RENAME_NOREPLACE, no MoveFileEx fallback), this stub returns ErrorKind::Unsupported. The operation is deliberately not emulated with a non-atomic check-then-rename, because that would lose the exclusivity guarantee.
Solutions
- Run on a platform whose libc provides atomic no-replace rename (Linux with renameat2, Windows MoveFileEx, macOS renamex_np)
- Upgrade the kernel/OS so the atomic-rename syscall is available
- File or contribute a platform implementation for rename_no_replace in principal_state/native_io.rs
- Restructure the caller to use a lock file or create-new (O_EXCL) protocol instead of exclusive rename if the platform truly cannot support it
Example fix
// before rename_no_replace(&src_dir, &src, &dst_dir, &dst)?; // Unsupported on this platform // after let opts = OpenOptions::new().write(true).create_new(true); let mut lock = opts.open(&dst)?; // O_EXCL claim, then write contents lock.write_all(&payload)?;
Defensive patterns
Strategy: fallback
Validate before calling
if !atomic_no_replace_rename_supported() {
// use lock-file or O_EXCL create protocol instead
use_create_new_protocol();
} Type guard
const EXCLUSIVE_RENAME_SUPPORTED: bool = cfg!(target_os = "linux") || cfg!(target_os = "windows");
Try / catch
match rename_result {
Err(e) if e.kind() == io::ErrorKind::Unsupported => {
// fall back to O_EXCL create-new claiming protocol
}
r => r,
} Prevention
- Confirm the target kernel/OS supports atomic no-replace rename before relying on exclusive renames
- Design callers with a fallback claiming protocol (create_new + write)
- Detect ENOSYS/Unsupported at startup rather than mid-transaction
- Keep the storage layer on platforms with full native_io support
When it happens
Trigger: Calling rename_no_replace on a platform where the cfg-gated native implementation is absent — the fallback body unconditionally errors. Any principal-state flow performing exclusive renames on such a target hits this.
Common situations: Porting the storage layer to an OS without renameat2/RENAME_NOREPLACE semantics; older kernels lacking renameat2 on Linux; exotic filesystems where the syscall returns ENOSYS at build-time feature detection.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- InvalidInput
- MCP gateway attach is only supported on Unix hosts
- MCP gateway cleanup is only supported on Unix hosts
- MCP gateway is only supported on Unix hosts
- MCP gateway readiness is only supported on Unix hosts
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/eb92a7f59c7e2876.
Report an issue: GitHub.
Appendix: source
Thrown at crates/astrid-storage/src/principal_state/native_io.rs:631
#[cfg(windows)]
fn rename_no_replace(
source_directory: &Dir,
source: &Path,
destination_directory: &Dir,
destination: &Path,
) -> std::io::Result<()> {
source_directory.rename(source, destination_directory, destination)
}
#[cfg(not(any(target_os = "linux", target_os = "macos", windows)))]
fn rename_no_replace(
_source_directory: &Dir,
_source: &Path,
_destination_directory: &Dir,
_destination: &Path,
) -> std::io::Result<()> {
Err(std::io::Error::new(
std::io::ErrorKind::Unsupported,
"capability-relative exclusive rename is unsupported",
))
}
pub(super) fn private_file_identity(file: &File) -> StorageResult<PrivateFileIdentity> {
let metadata = file
.metadata()
.map_err(|error| connection(format!("inspect private file handle: {error}")))?;
if !metadata.is_file() {
return Err(connection(
"private file handle is not a regular file".to_owned(),
));
}
#[cfg(windows)]
{
use std::os::windows::fs::MetadataExt as _;
use windows_sys::Win32::Storage::FileSystem::FILE_ATTRIBUTE_REPARSE_POINT;View on GitHub (pinned to affd8760f4)