{"record":{"id":"90505d283346eb7f","repo":"astrid-runtime/astrid","slug":"private-atomic-file-backend-is-selected-by-windows","errorCode":null,"errorMessage":"private atomic-file backend is selected by Windows callers only","messagePattern":"private atomic-file backend is selected by Windows callers only","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/astrid-core/src/platform_fs.rs","lineNumber":381,"sourceCode":"///\n/// Returns an error if the parent is not private, the destination is\n/// redirected or permissive, staging or sync fails, or atomic replacement\n/// fails.\npub fn atomic_write_private_file(path: &Path, bytes: &[u8]) -> io::Result<()> {\n    #[cfg(windows)]\n    {\n        windows::atomic_write_private_file(path, bytes)\n    }\n\n    #[cfg(unix)]\n    {\n        atomic_write_private_file_unix(path, bytes)\n    }\n\n    #[cfg(not(any(unix, windows)))]\n    {\n        let _ = (path, bytes);\n        Err(io::Error::new(\n            io::ErrorKind::Unsupported,\n            \"private atomic-file backend is selected by Windows callers only\",\n        ))\n    }\n}\n\n/// Reject redirecting path components at a security-sensitive boundary.\n///\n/// Windows checks the reparse attribute on every existing component, covering\n/// symlinks, junctions, and mount points. It also rejects parent owners or ACLs\n/// that let untrusted principals replace checked components, and identity-locks\n/// the chain while validating it. Unix opens the nearest existing directory\n/// authority and rejects a redirect at the requested or nearest-existing path;\n/// callers retain directory capabilities across multi-step mutations.\n///\n/// # Errors\n///\n/// Returns an error if an existing security-sensitive path is redirected,","sourceCodeStart":363,"sourceCodeEnd":399,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-core/src/platform_fs.rs#L363-L399","documentation":"atomic_write_private_file() dispatches to the Unix or Windows atomic write backend; there is no generic implementation. On any other target it returns io::ErrorKind::Unsupported because choosing an atomic, permission-preserving replace backend requires platform support.","triggerScenarios":"Calling atomic_write_private_file(path, bytes) on a non-unix/non-windows target — including indirect calls from journal publication, private create/write, and reader revalidation flows.","commonSituations":"Building the crate for wasm or an unsupported OS and attempting to write Astrid private state files; a caller that assumes the atomic-write API is portable.","solutions":["Use plain std::fs::write (accepting weaker guarantees) on unsupported targets, or gate atomic writes to unix/windows.","Branch at the call site on cfg!(any(unix, windows)) and provide a fallback strategy for other targets.","Implement a new platform backend in platform_fs.rs if atomic private writes must work on that target."],"exampleFix":"// before\natomic_write_private_file(&path, &bytes)?;\n// after\n#[cfg(any(unix, windows))]\natomic_write_private_file(&path, &bytes)?;\n#[cfg(not(any(unix, windows)))]\nstd::fs::write(&path, &bytes)?;","handlingStrategy":"fallback","validationCode":"let supported = cfg!(any(unix, windows));\nif supported {\n    atomic_write_private_file(&path, &bytes)?;\n} else {\n    std::fs::write(&path, &bytes)?;\n}","typeGuard":"fn supports_atomic_private_write() -> bool { cfg!(any(unix, windows)) }","tryCatchPattern":"match atomic_write_private_file(&path, &bytes) {\n    Err(e) if e.kind() == io::ErrorKind::Unsupported => std::fs::write(&path, &bytes)?,\n    other => other?,\n}","preventionTips":["Only use the atomic private-write API on unix/windows targets","Provide a non-atomic fallback write for other targets","Keep atomic-write usage inside cfg-guarded modules"],"tags":["io","filesystem","atomic-write","platform-specific"],"backgroundTag":"unsupported-platform","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}