{"record":{"id":"743f95007aff9367","repo":"wasmerio/wasmer","slug":"wasi-path-unlink-file-for-buffer","errorCode":null,"errorMessage":"wasi::path_unlink_file for Buffer","messagePattern":"wasi::path_unlink_file for Buffer","errorType":"panic","errorClass":"panic","httpStatus":null,"severity":"error","filePath":"lib/wasix/src/syscalls/wasi/path_unlink_file.rs","lineNumber":135,"sourceCode":"                        wasi_try_ok!(h.unlink().map_err(fs_error_into_wasi_err));\n                    } else {\n                        // File is closed\n                        // problem with the abstraction, we can't call unlink because there's no handle\n                        // drop mutable borrow on `path`\n                        let path = path.clone();\n                        drop(guard);\n                        wasi_try_ok!(state.fs_remove_file(path));\n                    }\n                }\n                Kind::Dir { .. } | Kind::Root { .. } => return Ok(Errno::Isdir),\n                Kind::Symlink { .. } => {\n                    drop(guard);\n                    let errno = state.fs.remove_symlink_file(host_adjusted_path.as_path());\n                    if errno != Errno::Success {\n                        return Ok(errno);\n                    }\n                }\n                _ => unimplemented!(\"wasi::path_unlink_file for Buffer\"),\n            }\n        }\n    }\n\n    Ok(Errno::Success)\n}\n","sourceCodeStart":117,"sourceCodeEnd":142,"githubUrl":"https://github.com/wasmerio/wasmer/blob/8c4b9ee9d33fb2068863fbb3d328683e7e6ff7f5/lib/wasix/src/syscalls/wasi/path_unlink_file.rs#L117-L142","documentation":"The wasi path_unlink_file syscall does not handle buffer-backed inodes. In path_unlink_file_internal, the match arms handle symlink/file removal via the FS layer, but the catch-all _ arm hits unimplemented! when the target inode (or matched kind) is a Buffer. Unlinking buffer nodes was simply never implemented.","triggerScenarios":"Guest calls wasi.path_unlink_file on a path that resolves to a Kind::Buffer node in the synthetic FS tree (e.g. an in-memory blob registered as a Buffer), instead of a regular file or symlink.","commonSituations":"Guests that 'clean up' temp files inside preopened in-memory filesystems where drivers create Buffer nodes; apps ported from other wasi runtimes where buffers are deletable.","solutions":["Remove the buffer node through the buffer-management API (drop/replace it in the FS tree) instead of path_unlink_file.","Pre-check the resolved inode Kind and return Errno::Notsup for buffers instead of calling through.","Register such blobs as Kind::File if unlink semantics are required.","Implement the Buffer arm by detaching the buffer from its parent directory."],"exampleFix":"// before\npath_unlink_file(\"/memfs/tmp.bin\") // tmp.bin is a Buffer -> panic\n\n// after (guard)\nif matches!(&*inode.read(), Kind::Buffer { .. }) {\n    return Ok(Errno::Notsup);\n}","handlingStrategy":"type-guard","validationCode":"// resolve and check the kind before unlinking\nfn unlinkable(state: &FsState, path: &Path) -> bool {\n    match state.fs.get_inode_at_path(path) {\n        Ok(inode) => !matches!(&*inode.read(), Kind::Buffer { .. }),\n        Err(_) => false,\n    }\n}","typeGuard":"fn is_buffer_inode(inode: &Inode) -> bool {\n    matches!(&*inode.read(), Kind::Buffer { .. })\n}","tryCatchPattern":"let r = std::panic::catch_unwind(AssertUnwindSafe(|| path_unlink_file_internal(state, path, follow))); \nif r.is_err() { return Ok(Errno::Notsup); }","preventionTips":["Do not register cleanup-able temp files as Kind::Buffer nodes","Delete buffers through their owning driver API, not wasi.path_unlink_file","Check resolved inode kind before unlink and surface Errno::Notsup"],"tags":["wasix","wasi","unlink","buffer","unimplemented"],"backgroundTag":"unsupported-inode-kind","analyzedSha":"8c4b9ee9d33fb2068863fbb3d328683e7e6ff7f5","analyzedAt":"2026-09-01T23:06:31.009Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}