wasmerio/wasmer · error · panic

state::get_inode_at_path for buffers

Error message

state::get_inode_at_path for buffers

What it means

state::get_inode_at_path resolves a path component-by-component through the in-memory FS tree. When it walks into an inode of Kind::Buffer (an in-memory buffer-backed node), the resolution logic has no implementation, so it panics with unimplemented!. Buffer nodes cannot be traversed/consulted during path lookup yet.

Source

Thrown at lib/wasix/src/fs/mod.rs:1346

                }
                PosixPathComponent::Normal(component) => component,
                PosixPathComponent::RootDir => unreachable!("RootDir is handled above"),
            };

            'component_lookup: loop {
                // 1. Read-Only Lookup Phase
                // --
                // Match current inode against known entry types, and if it happens
                // to be a directory, then resolve current component as an entry in
                // that directory.
                // Note: this loop practically never does more than one iteration.
                // There is only one exotic case when this loop would do another
                // iteration, and it is when current inode happens to be Root
                // containing '/' entry.
                let component_resolution = {
                    match cur_inode.clone().read().deref() {
                        Kind::Buffer { .. } => {
                            unimplemented!("state::get_inode_at_path for buffers")
                        }
                        Kind::File { .. }
                        | Kind::Socket { .. }
                        | Kind::PipeRx { .. }
                        | Kind::PipeTx { .. }
                        | Kind::DuplexPipe { .. }
                        | Kind::EventNotifications { .. }
                        | Kind::Epoll { .. } => {
                            return Err(Errno::Notdir);
                        }
                        Kind::Symlink { .. } => break 'component_lookup,
                        Kind::Root { entries } => {
                            if let Some(entry) = entries.get(component_str) {
                                cur_inode = entry.clone();
                                break 'component_lookup;
                            } else if let Some(root) = entries.get("/") {
                                // This is quite exotic case where Root itself
                                // has '/' entry in it, and we want to follow

View on GitHub (pinned to 8c4b9ee9d3)

Solutions

  1. Do not place Kind::Buffer nodes where path resolution must traverse them; use Kind::File or a real directory-backed node instead.
  2. Resolve to the buffer's inode directly by handle rather than by path traversal.
  3. Pre-check the tree (inspect inode Kind before path resolution) and return Errno::Notsup / Badf for buffer nodes instead of reaching the panic.
  4. Implement the Buffer arm in get_inode_at_path if you control the source.

Example fix

// before: resolving a path through a buffer node panics
state.get_inode_at_path(cur_dir, "/memfs/blob.txt")?

// after: guard the node kind first
if matches!(&*inode.read(), Kind::Buffer { .. }) {
    return Err(Errno::Notsup);
}
Defensive patterns

Strategy: type-guard

Validate before calling

// check inode kind before path resolution / traversal
fn is_buffer(inode: &Inode) -> bool {
    matches!(&*inode.read(), Kind::Buffer { .. })
}

Type guard

fn as_buffer(guard: &InodeGuard) -> Option<BufferHandle> {
    match &*guard.read() {
        Kind::Buffer { .. } => None, // unsupported for path resolution
        _ => Some(()),
    }.map(|_| ())
}

Try / catch

let result = std::panic::catch_unwind(|| state.get_inode_at_path(dir, path));
match result {
    Ok(Ok(inode)) => inode,
    _ => return Err(Errno::Notsup),
};

Prevention

When it happens

Trigger: Calling any WASI path API that internally resolves a path (fd_open / path_open family, stat, etc.) where an intermediate or final component of the resolved path lands on a Kind::Buffer inode — e.g. looking up a child under a buffer-backed node.

Common situations: Guest programs open paths inside synthetic FS trees where a driver registered a Buffer inode (preopened in-memory blobs) and the guest treats it like a directory or resolves through it; also mismatched expectations that buffers behave like regular files in path lookups.

Related errors


AI-assisted analysis of wasmerio/wasmer@8c4b9ee9d3 (2026-09-01). Data as JSON: /api/errors/a1f927a2581ad43e. Report an issue: GitHub.