{"record":{"id":"95c64b62cefe6b0a","repo":"astrid-runtime/astrid","slug":"layout-migration-capacity-probing-is-unavailable-i","errorCode":null,"errorMessage":"layout migration capacity probing is unavailable in a WebAssembly guest","messagePattern":"layout migration capacity probing is unavailable in a WebAssembly guest","errorType":"exception","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"crates/astrid-core/src/dirs_layout.rs","lineNumber":501,"sourceCode":"fn ensure_available_migration_capacity(available: u64, source_bytes: u64) -> io::Result<()> {\n    let required = source_bytes\n        .checked_mul(2)\n        .and_then(|bytes| bytes.checked_add(LAYOUT_MIGRATION_HEADROOM_BYTES))\n        .ok_or_else(|| io::Error::other(\"layout migration capacity requirement overflow\"))?;\n    if available < required {\n        return Err(io::Error::new(\n            io::ErrorKind::StorageFull,\n            format!(\n                \"insufficient free space for layout migration: need {required} bytes, have {available} bytes\"\n            ),\n        ));\n    }\n    Ok(())\n}\n\n#[cfg(target_family = \"wasm\")]\nfn ensure_migration_capacity(_target: &Path, _source_bytes: u64) -> io::Result<()> {\n    Err(io::Error::new(\n        io::ErrorKind::Unsupported,\n        \"layout migration capacity probing is unavailable in a WebAssembly guest\",\n    ))\n}\n\nfn atomic_write(path: &Path, bytes: &[u8]) -> io::Result<()> {\n    #[cfg(windows)]\n    {\n        crate::platform_fs::atomic_write_private_file(path, bytes)\n    }\n\n    #[cfg(unix)]\n    {\n        use std::os::unix::fs::OpenOptionsExt as _;\n\n        let parent = path.parent().ok_or_else(|| {\n            io::Error::new(io::ErrorKind::InvalidInput, \"layout record has no parent\")\n        })?;","sourceCodeStart":483,"sourceCodeEnd":519,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-core/src/dirs_layout.rs#L483-L519","documentation":"This io::Error with ErrorKind::Unsupported is thrown by the wasm-specific stub of ensure_migration_capacity in dirs_layout.rs. Before writing a new layout record the library probes whether the target filesystem/volume has enough capacity for the migrated layout; that capacity probing requires OS filesystem APIs that do not exist inside a WebAssembly guest. The function therefore unconditionally fails when layout migration would need to run under wasm.","triggerScenarios":"Calling write_layout_version (directly or through a layout migration such as begin_layout_v2_migration) compiled to a wasm target, when the target size check path needs ensure_migration_capacity to verify source_bytes fit at _target.","commonSituations":"Running the crate in a browser/WASI sandbox (e.g. in a Cloudflare Worker, browser wasm module, or wasmtime) and attempting a layout v1->v2 migration; embedding astrid-core in a wasm build where directory-layout upgrades were assumed to work like on desktop targets.","solutions":["Do not run layout migrations inside wasm; perform them on a native (unix/windows) host before shipping data to the wasm environment.","Gate the migration call behind a target-family check in your own code (#[cfg(not(target_family = \"wasm\"))]) and skip or defer it in wasm builds.","Pre-ensure capacity externally (mount a larger volume / free space) and use an API path that does not trigger capacity probing.","File/verify wasm support status for this operation in the crate docs; treat it as a hard unsupported operation."],"exampleFix":"// before (wasm guest)\nwrite_layout_version(&dir, &record)?;\n// after\n#[cfg(not(target_family = \"wasm\"))]\nwrite_layout_version(&dir, &record)?;\n#[cfg(target_family = \"wasm\")]\n// defer migration to a native host step","handlingStrategy":"fallback","validationCode":"#[cfg(target_family = \"wasm\")]\nfn migration_supported() -> bool { false }\n#[cfg(not(target_family = \"wasm\"))]\nfn migration_supported() -> bool { true }","typeGuard":"fn supports_layout_migration() -> bool {\n    !cfg!(target_family = \"wasm\")\n}","tryCatchPattern":"match write_layout_version(&dir, &record) {\n    Err(e) if e.kind() == io::ErrorKind::Unsupported => defer_migration_to_native_host(),\n    other => other?,\n}","preventionTips":["Check cfg!(target_family = \"wasm\") before invoking layout migration APIs","Run migrations on a native host before deploying data to wasm guests","Document platform support per operation in your build pipeline"],"tags":["wasm","filesystem","unsupported-platform","migration"],"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"}