Skip to content

bridge fs: realpathSync silently returns a truncated path when a segment fails with an unexpected error #1838

Description

@atsushi-ishibashi

Problem

In the sandbox bridge's custom realpathSync implementation (packages/build-tools/bridge-src/builtins/fs.ts), the segment-resolution loop lstatSyncs each path segment inside a try/catch. The catch only handles ELOOP (rethrow) and ENOENT / ENOTDIR (mapped to ENOENT) specially; any other error (e.g. EACCES from the underlying stat/readlink) hits a bare break. The function then returns the partially-resolved path — the remaining unprocessed segments are silently dropped — instead of propagating the error.

Impact

A caller gets a valid-looking but wrong path (typically the parent directory of the requested file). We hit this class of bug on 0.1.x (@secure-exec/nodejs): the Claude CLI resolves paths with realpathSync before reading, received the truncated parent directory path, and every Edit/Write failed with EISDIR: illegal operation on a directory, read. The old trigger (mount-root lstat returning EACCES in the JS host-dir backend) is gone in the Rust VFS, but the truncation pattern itself is still present, so any host backend that returns an unexpected errno for a path segment reintroduces silent misresolution.

Since the bridge is compiled into the sidecar binary, embedders cannot work around this locally.

Suggested fix

Treat unexpected errors as fatal for the resolution: rethrow (mapped to the original errno) instead of break, so callers see EACCES etc. rather than a truncated path.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions