rules_js icon indicating copy to clipboard operation
rules_js copied to clipboard

[Bug]: fs.readlinkSync converts relative symlinks to absolute paths

Open ashi009 opened this issue 4 months ago • 0 comments

What happened?

Description

The fs.readlinkSync function in rules_js fs patches incorrectly converts relative symlinks to absolute paths. This breaks the intended relative nature of symlinks, causing issues when symlinks need to remain portable (e.g., when moving directories or using relative paths for portability).

Root Cause

In js/private/node-patches/src/fs.cts, the readlinkSync and readlink functions use path.resolve() to convert the symlink target to an absolute path:

const str = path.resolve(
    path.dirname(resolved),
    origReadlinkSync(...args)
)

This always returns an absolute path, even when the original symlink was created with a relative target.

Expected Behavior

Relative symlinks should remain relative when read via fs.readlinkSync(). The function should preserve the original relative path that was used when creating the symlink.

Actual Behavior

fs.readlinkSync() converts relative symlink targets to absolute paths, breaking symlink portability.

Version

Development (host) and target OS/architectures: macOS

Output of bazel --version: 8.0.0

Version of the Aspect rules, or other relevant rules from your WORKSPACE or MODULE.bazel file: 2.5.0

Language(s) and/or frameworks involved: no

How to reproduce

### Minimal Repository
https://github.com/ashi009/rules_js-fs-patch-bug

### Steps to Reproduce
1. Clone the reproduction repository
2. Run `bazel run //:test`
3. Observe the output showing the difference between unpatched and patched behavior

Any other information?

Test Output

=== Original Node.js fs behavior ===
Unpatched readlinkSync result: ../test-symlinks/target.txt
Expected: relative path preserved

=== With rules_js fs patches ===
Patched readlinkSync result: /absolute/path/to/target.txt

=== Comparison ===
Original (correct): ../test-symlinks/target.txt
Patched (incorrect): /absolute/path/to/target.txt
Bug: CONFIRMED - relative symlink converted to absolute!

Impact

This bug affects:

  • Portable symlinks that need to work when directories are moved
  • Build systems that rely on relative symlinks
  • Any application that expects readlinkSync() to preserve relative paths
  • Cross-platform compatibility where absolute paths differ

Additional Context

  • The issue is reproducible across all platforms
  • Both readlinkSync and readlink (async version) are affected
  • The bug was introduced in the fs patching system that converts paths for Bazel compatibility

ashi009 avatar Sep 01 '25 05:09 ashi009