Skip to content

install: stop panicking on bin values longer than the path buffer - #38954

Open
robobun wants to merge 7 commits into
mainfrom
farm/46e17864/install-long-bin-target
Open

install: stop panicking on bin values longer than the path buffer#38954
robobun wants to merge 7 commits into
mainfrom
farm/46e17864/install-long-bin-target

Conversation

@robobun

@robobun robobun commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator

Problem

  • bun install aborts with panic: range end index 5038 out of range for slice of length 4095 (exit 134 plus a crash report) when a dependency's package.json has a bin value longer than 4 KiB: the string form, a value in the object form, or directories.bin. Both linkers are affected, and so are bun link and bun unlink for a package with such a value. Repro below.
  • Cause: Linker::resolve_bin_target (src/install/bin.rs:1479-1519 on main) and the directories.bin arms of link (bin.rs:1772) and unlink (bin.rs:1940) join the value onto the package directory with resolve_path::join_abs_string_z, which normalizes into a fixed 4096 byte thread-local buffer with no bounds check (normalize_string_generic_tz in src/paths/resolve_path.rs, top frame of the crash). The linker length-checks bin names (the .bin/<name> side) but never the value, and values are stored as written, from the registry manifest or the lockfile.
  • Two more joins in the same file overflow once a bin directory is itself close to PATH_MAX: every entry of the directory is joined onto it into abs_target_buf (bin.rs:1805), and the temporary file for rewriting a CRLF shebang, 27 bytes longer than the target, is joined the same way (bin.rs:1045). Panics range end index 4160 and 4111 respectively with the test below.
  • One step later, create_symlink (bin.rs:1266) computes the relative link target into rel_buf, another PathBuffer, unchecked. The relative form gains a .. per component of the bin directory that the target does not share, so with a global bin directory (BUN_INSTALL_BIN, install.globalBinDir) on another branch of the tree it can be longer than the absolute target; a target within a few bytes of the limit that the joins above accept then aborts bun link / bun add -g with range end index 4198 out of range for slice of length 4096. Pre-existing as well, found while reviewing this change.

Fix

  • All six joins go through one helper, Linker::join_z_checked, which uses the existing resolve_path::join_abs_string_buf_checked into a PathBuffer sized buffer and returns None when the normalized path does not fit. The resolved target gets a pooled buffer, because abs_target_buf holds the package directory the value is joined onto. resolve_bin_target returns Option accordingly.
  • Why these outcomes are the right ones: a PathBuffer is exactly the size the bun_sys wrappers copy a path into, so "does not fit" is precisely the set of paths they already refuse (sys::exists returns false for them, sys::open_dir_absolute returns ENAMETOOLONG). Each caller takes the branch it takes for that answer, one step earlier, so a value that does not fit now behaves exactly like a value that fits but that the OS rejects (for example a 300 byte single component) behaves on the current release:
    • file targets (string, one entry, map, and the entries of a bin directory): skipped like a missing bin, the rest of the install is unaffected and the exit code is 0. npm does the same: bin-links ignores a target it cannot lstat.
    • directories.bin: ENAMETOOLONG, which the link arm already reports for every open failure other than ENOENT. Hoisted prints error: Failed to link <pkg>: ENAMETOOLONG and exits 1 with everything else installed and linked, isolated prints its failed to link binaries for package line, bun link prints failed to link bin due to error ENAMETOOLONG, and bun unlink (which ignores linker errors) still unlinks the package.
    • the shebang rewrite already gives up on any error, so it gives up; the bin is linked and keeps its CRLF shebang.
  • The check is on the normalized length, so a long value that normalizes to a short path (x/../x/../.../cli.js, 100 kB as written) still links; the test pins this, it passes before and after.
  • The native binlink redirect probes the same candidates in the same order (value, bin name, basename of the value, bin name plus .exe); a candidate that does not fit is skipped and the next one is probed, and when nothing is found the usual retry without the redirect happens. Because the result now borrows a local buffer instead of the thread-local one, the unsafe lifetime detaches for abs_target in link and for package_dir in unlink are gone.
  • create_symlink computes an upper bound for the relative target (target length + 3 per component of the bin directory) and uses a heap buffer instead of rel_buf when that bound does not fit, which only happens with a target within a few hundred bytes of the limit. Nothing else changes: a relative target that really is too long is handed to symlink(2), which reports ENAMETOOLONG like any other link error (bun link prints failed to link bin due to error ENAMETOOLONG), and one that fits after all is created. The Windows shim writer has the same call, but its buffer is about 96 KiB, larger than any target NTFS can hold unless the whole path is 3 byte characters, and install(windows): store an absolute target in .bunx shims when the package dir is on another drive #38018 is reworking that code, so it is left alone.
  • Verified with test/cli/install/bun-install-registry.test.ts, new block binaries > bin values longer than the path buffer (7 tests): the three file shapes plus the normalizing value, with each linker, installed twice (the second time from the lockfile); directories.bin with each linker; a bin directory 64 bytes below the limit holding a short entry (linked), a CRLF entry whose temp file would not fit (linked, shebang left alone) and an entry that does not fit (skipped); bun link with a bin directory below the global directory (the bound is exceeded but the target fits, so it is linked, and the link is checked) and then with one far enough away that the target does not fit (ENAMETOOLONG, exit 1, nothing linked); bun link and bun unlink of a package with each shape. All seven fail on the current release (six panic in the joins, the bun link one with the length 4096 panic above) and pass with this change. The values are 100 kB so the Windows buffer is exceeded as well; the two near-the-limit tests are POSIX only, since the Windows buffer is larger than any path the filesystem accepts, and they keep most of the depth in the project directory rather than inside the package because the .bin links are relative and XFS (the Alpine CI lanes) rejects symlink targets of 1 KiB or more.
  • test/cli/install/bun-install-native-binlink.test.ts gets a fourth altpath shape (fixture version 4.0.0, only the new tarballs and manifest entries are added): the parent's bin value is 8 KiB, so in redirect mode the first candidate cannot be built and the bin has to be linked from <platform package>/<bin name>. Both linker variants panic on the current release (range end index 8271) and pass with this change; on Windows the value fits and the shape degrades to an ordinary miss of the first candidate.
  • Also run with the debug build: the rest of bun-install-registry.test.ts, bun-install-native-binlink.test.ts (18), symlink-path-traversal.test.ts (12), shebang-normalize.test.ts.
  • Related: pack/publish: stop panicking on package.json bin and files entries longer than the path buffer #38784 fixes the same input for bun pm pack / bun publish and left the install side for a separate change; Bun.build: report an error for HTML rooted script src paths >= 4096 bytes instead of aborting #35860 and bun test: stop panicking on a path argument or tree entry longer than the path buffer #35863 change the shared join primitive. This change does not depend on them and is unaffected by them: it sizes the path before the primitive runs and reports what the OS would have reported, instead of handing an oversized or emptied path on to the next syscall.

Background

  • Bin linking: for every entry of a package's bin, Linker::link in src/install/bin.rs creates node_modules/.bin/<name> (a .bunx plus .exe shim on Windows, or a global bin) pointing at <package dir>/<value>. After parsing, bin has one of four shapes: a string (File), a one entry object (NamedFile), a larger object (Map), or directories.bin (Dir, which links every file in that directory). The hoisted and isolated installers, bun link and bun unlink all share this code.
  • PathBuffer / MAX_PATH_BYTES: bun's buffer for a path that is about to be handed to the OS, sized to the platform PATH_MAX (4096 on Linux, 1024 on macOS, about 96 KiB on Windows). The bun_sys wrappers that accept a byte slice copy it into one and refuse anything longer. join_abs_string_z, the join used here before, instead writes into a 4096 byte thread-local on every platform and assumes the result fits.
  • join_abs_string_buf_checked is the join variant for parts of arbitrary length: it normalizes (into a heap scratch when necessary) and returns None only when the normalized result does not fit the caller's buffer. It is what folder dependency paths (lockfile/Package.rs) and, since install: stop panicking on workspaces entries longer than the path buffer #37531, workspace entries use.
  • Native binlink redirect: for packages such as esbuild, the bin declared by the root package is linked straight to the file inside the platform specific optional dependency, whose layout may differ; that is why resolve_bin_target joins several candidate paths and checks which exists.
  • The link is created with a relative target (../<pkg>/<value> for a project, whatever path.relative(bin dir, target) gives for a global bin directory), computed by resolve_path::relative_buf_z into the caller's buffer; that is the computation the create_symlink bullet is about.
  • skipped_due_to_missing_bin: set by the linker when a target does not exist on disk. The installers use it to retry once without the redirect and otherwise ignore it, which is what makes "treat an unbuildable path as missing" fit in without new plumbing.
Repro on the current release (1.4.0-canary.1) and output with this change
mkdir -p r/dep r/app && cd r
bun -e 'const fs = require("fs"); const long = Buffer.alloc(5000, "b").toString();
fs.writeFileSync("dep/package.json", JSON.stringify({ name: "dep", version: "1.0.0", bin: { cli: long, ok: "ok.js" } }));
fs.writeFileSync("dep/ok.js", "#!/usr/bin/env node\n");
fs.writeFileSync("app/package.json", JSON.stringify({ name: "app", dependencies: { dep: "file:../dep" } }))'
cd app && bun install

Release: panic: range end index 5038 out of range for slice of length 4095, exit 134, with --linker isolated as well. Same with bin: long and with directories: { bin: long }, and for bun link / bun unlink run inside dep.

With this change:

input hoisted isolated bun link
bin: long, bin: { cli: long }, bin: { cli: long, ok: "ok.js" } exit 0, only ok linked exit 0, only ok linked exit 0, only ok linked
directories: { bin: long } error: Failed to link dep: ENAMETOOLONG, exit 1, other packages and bins installed ENAMETOOLONG: failed to link binaries for package: dep@../dep, exit 1 error: failed to link bin due to error ENAMETOOLONG, exit 1; bun unlink afterwards succeeds

This is the same output the release produces today for directories: { bin: "b".repeat(300) } or bin: { cli: "b".repeat(300) }, where the OS is the one rejecting the path.

The bin linker joined each bin target onto the package directory with
join_abs_string_z, which writes into a fixed 4096 byte buffer without a
bounds check, so a dependency whose package.json bin value (or
directories.bin) did not fit aborted bun install, bun link and bun
unlink. The joins of a bin directory's entries and of the temporary
file used to rewrite a CRLF shebang overflowed the same way once the
directory itself was close to PATH_MAX.

Join into a PathBuffer with join_abs_string_buf_checked instead. A
path that does not fit takes the branch the sys layer already takes
for such a path: file targets are skipped like a missing bin
(sys::exists reports them missing), a bin directory is reported as
ENAMETOOLONG (what sys::open_dir_absolute returns for it), and the
shebang rewrite, which ignores every other failure, is skipped.
@coderabbitai

coderabbitai Bot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@robobun, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 28 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 6628f14a-0149-4663-9404-3a2e79e97b87

📥 Commits

Reviewing files that changed from the base of the PR and between 9fb606f and eecb876.

📒 Files selected for processing (8)
  • src/install/bin.rs
  • test/cli/install/bun-install-native-binlink.test.ts
  • test/cli/install/bun-install-registry.test.ts
  • test/cli/install/registry/packages/create-native-binlink-altpath-packages.ts
  • test/cli/install/registry/packages/test-native-binlink-altpath-target/package.json
  • test/cli/install/registry/packages/test-native-binlink-altpath-target/test-native-binlink-altpath-target-4.0.0.tgz
  • test/cli/install/registry/packages/test-native-binlink-altpath/package.json
  • test/cli/install/registry/packages/test-native-binlink-altpath/test-native-binlink-altpath-4.0.0.tgz

Comment @coderabbitai help to get the list of available commands.

@robobun

robobun commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator Author

Status: reproduced and fixed.

  • Reproduced on 1.4.0-canary.1: bun install (hoisted and isolated), bun link and bun unlink abort with panic: range end index N out of range for slice of length 4095 for a bin string, a bin object value and directories.bin longer than 4 KiB; the entry join and the shebang temp file join overflow the same way for a bin directory near PATH_MAX (indexes 4160 and 4111).
  • Fix and tests are in this PR; the 6 new tests in test/cli/install/bun-install-registry.test.ts fail on the current release and pass with the change, and the rest of that file plus the native binlink, symlink traversal and shebang tests pass with a debug build.

@robobun

robobun commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator Author
Updated 12:05 PM PT - Aug 15th, 2026

@robobun, your commit eecb876 has some failures in Build #98157 (All Failures)


🧪   To try this PR locally:

bunx bun-pr 38954

That installs a local version of the PR into your bun-38954 executable, so you can run:

bun-38954 --bun

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reviewed this PR and didn't find any bugs. Because it refactors resolve_bin_target's control flow and changes buffer ownership in the bin linker (a path that runs on every install and sits next to the CVE-2019-16775 traversal guards), a human look would still be worthwhile.

Checked: the candidates loop preserves the original probe order and empty-skip conditions; join_z_checked reserves the NUL byte correctly against join_abs_string_buf_checked; the pooled resolved_target_buf outlives every abs_target borrow so the removed ZStr::from_raw detaches are sound to drop; bin_target_escapes_package_dir still runs before every changed join. Tests cover File/NamedFile/Map/Dir × both linkers, lockfile round-trip, the normalizing-long-value case, and bun link/unlink.

Extended reasoning...

Overview

This PR replaces six unchecked path joins in src/install/bin.rs (Linker::resolve_bin_target, the Dir arms of link/unlink, the per-entry join inside a bin directory, and the CRLF-shebang temp file) with a single join_z_checked helper built on the existing resolve_path::join_abs_string_buf_checked. resolve_bin_target now returns Option<&ZStr> and writes into a caller-supplied pooled PathBuffer instead of the thread-local join buffer, which lets three unsafe { ZStr::from_raw(...) } lifetime detaches in link and one raw-pointer package_dir detach in unlink be deleted. ~260 lines of new tests in bun-install-registry.test.ts cover every bin shape across both linkers, plus bun link/unlink and a POSIX-only near-PATH_MAX directory.

Security risks

Bin linking is security-adjacent: it creates symlinks into .bin and lchmods targets, and this file already carries the CVE-2019-16775 traversal guard. I verified bin_target_escapes_package_dir and bin_target_needs_resolved_containment_check still gate every changed call site before the join runs, and that join_z_checked normalizes (so the long-but-normalizes-short test case does not open a bypass). The change narrows behavior — a value that used to panic now takes the same branch the OS's ENAMETOOLONG/missing-file answer would have taken — rather than accepting anything new. No new unsafe is added; four unsafe blocks are removed.

Level of scrutiny

Medium-high. The fix itself is a straightforward "use the checked join" swap, but it comes with a control-flow refactor of resolve_bin_target (sequential ifs → candidate array + loop) and a buffer-ownership change (thread-local → pooled local). I traced the candidate order (target, bin_name, basename-if-has-dir-component, bin_name+.exe) against the old code and it matches, including the fall-through-to-primary when nothing exists; the ZStr::from_buf(buf, len) re-derivation inside the loop is the standard NLL workaround and the NUL at buf[len] is written by join_z_checked. The pooled buffer's PoolGuard lives for all of link(), so abs_target never dangles. Still, this runs on every bun install and the refactor is non-mechanical enough that a maintainer should confirm the shape.

Other factors

The PR description is unusually thorough — every outcome is justified against what the OS already reports for a shorter-but-still-rejected path, and the test matrix is comprehensive (including the second-install-from-lockfile round trip and the near-limit directory that exercises the entry-join and shebang-temp-file overflows). The bug hunting system found nothing. The one behavioral nuance worth a maintainer's eye is that in the native-binlink-redirect path, exe_name is now allocated unconditionally (as an empty Vec when unused) rather than lazily; this is cold-path and harmless but is the kind of micro-shape a reviewer might want to weigh in on.

XFS rejects symlink targets of 1 KiB or more, so the Alpine lanes failed
to link the entries that fit. Put most of the depth into the project
directory instead of the package so the relative link targets stay
short while the bin directory still ends up 64 bytes below the limit.
Comment thread src/install/bin.rs Outdated
Comment thread src/install/bin.rs Outdated
Comment thread src/install/bin.rs Outdated
Comment thread src/install/bin.rs Outdated
Comment thread src/install/bin.rs Outdated
Comment thread src/install/bin.rs Outdated
Comment thread src/install/bin.rs Outdated
Comment thread src/install/bin.rs Outdated

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reviewed this PR and didn't find any bugs. Because it refactors buffer ownership and unsafe lifetime handling in the bin linker (a hot path shared by every install, bun link, and bun unlink), a human look would still be worthwhile.

What was reviewed:

  • join_z_checked reserves one byte for the NUL and join_abs_string_buf_checked bounds the result to buf.len()-1, so buf[len] = 0 is always in bounds; ZStr::from_buf invariants hold.
  • resolve_bin_target candidate order and gating (target → bin_name → basename-only-if-target-has-a-dir → bin_name.exe) is preserved; sys::exists_z is what sys::exists already delegated to.
  • The pooled resolved_target_buf is disjoint from self, so the removed ZStr::from_raw detaches for abs_target are no longer needed; the remaining from_raw in the Tag::Dir entry loop still points into abs_target_buf and its SAFETY note is unchanged.
  • None outcomes route to the same branches the OS's ENAMETOOLONG already reached (skipped_due_to_missing_bin for file targets, self.err for directories.bin, silent give-up for the shebang temp file).
Extended reasoning...

Overview

The PR replaces six unchecked path joins in src/install/bin.rs (resolve_bin_target, the Tag::Dir arms of link/unlink, the Tag::Dir entry loop, and the CRLF-shebang temp file) with a single join_z_checked helper that uses resolve_path::join_abs_string_buf_checked and returns None when the normalized result would not fit a PathBuffer. resolve_bin_target is refactored from an unrolled sequence into an array of candidates and now writes into a caller-supplied buffer (a pooled PathBuffer in link, a fresh pool buffer in unlink's Dir arm) instead of the thread-local join buffer, which lets three unsafe ZStr::from_raw lifetime detaches be dropped. Six new tests in bun-install-registry.test.ts cover the string/single-entry/map bin shapes plus a normalizing-to-short value across both linkers and from the lockfile, directories.bin across both linkers, a bin directory near PATH_MAX (POSIX-only), and bun link/bun unlink.

Security risks

None introduced. The change tightens bounds checking on untrusted bin values from package.json/registry manifests/lockfiles — previously a value ≥4 KiB triggered a slice-index panic (a DoS on any project depending on such a package). The existing path-traversal guards (bin_target_escapes_package_dir, resolved_target_parent_escapes_package_dir) run before/after the join and are untouched. The None path maps to "treat as nonexistent" for file targets (matching npm's bin-links) and ENAMETOOLONG for directories.bin (matching what open_dir_absolute already returned for a fitting-but-too-long path).

Level of scrutiny

High. This is the bin linker shared by hoisted install, isolated install, bun link and bun unlink; it runs for every package with a bin field. The file carries substantial unsafe (raw-pointer detaches for disjoint borrows, ZStr::from_raw, union field reads) and the PR both adds a pooled buffer to link() and rewrites the candidate-probing loop. I verified the helper's bounds arithmetic, that sys::exists_z is semantically identical to the previous sys::exists on these inputs, that the candidate order/gating is preserved bit-for-bit, and that each None branch reaches the same terminal state the OS would have produced — but the combination of buffer-ownership reshuffling and control-flow refactor in memory-safety-adjacent code warrants a maintainer's eyes.

Other factors

  • The comment-cop bot flagged long comments on earlier commits; the author trimmed them in ea679068 and e70b86b9 and all eight threads are marked resolved.
  • Test coverage is thorough: each shape × each linker, lockfile round-trip, the near-PATH_MAX directory case that exercises the entry join and shebang-tmpfile join, and bun link/bun unlink. The author reports the rest of bun-install-registry.test.ts, bun-install-native-binlink.test.ts, symlink-path-traversal.test.ts, and shebang-normalize.test.ts pass on the debug build.
  • The pooled buffer is acquired once per link() call (not per entry), so no per-bin allocation overhead in the Map/Dir loops.

@robobun

robobun commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator Author

Follow-ups since the PR was opened:

  • The only CI failure was the new "entries of a directories.bin close to the path limit" test, on the two Alpine lanes: Failed to link deep-dir-bin: ENAMETOOLONG. The .bin links are relative, so the whole chain of directories below the package ended up in the link target (about 4 kB), and XFS refuses symlink targets of 1 KiB or more; the other lanes run on filesystems without that limit. e766739 keeps the same overflow setup (bin directory 64 bytes below the limit, entries that fit / fit without their shebang temp file / do not fit) but puts most of the depth into the project directory, so the link targets are about 750 bytes. It still panics on the current release (range end index 4111) and passes with the change, and it now also checks where the two links point.
  • On the review note about exe_name: Vec::new() does not allocate, so the non-redirect and no-.exe cases do not pay for it; the allocation only happens when that candidate is actually probed, as before.
  • The comment-cop threads are addressed in ea67906 and e70b86b (comments trimmed to one line each or deleted, no code change); GitHub is currently rejecting per-thread replies from this account, so they are resolved without one.

The .bin link is relative to the bin directory, and each component of a
global bin directory that is not shared with the target adds a "..", so
the link target can be longer than the target's absolute path. When the
absolute path was within a few bytes of the buffer, relative_buf_z
overflowed rel_buf and bun link / bun add -g aborted. Compute into a
heap buffer when the upper bound does not fit; symlink(2) then reports
ENAMETOOLONG for a target that is really too long, like any other link
error.
…e path buffer

Adds a 4.0.0 shape to the altpath fixtures: the parent's bin value is
8 KiB, so the first candidate cannot be built and the redirect has to
move on to <pkg>/<bin_name>. Only the 4.0.0 tarballs and manifest
entries are added; the existing fixtures are unchanged.
@robobun

robobun commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator Author

Two additions after going over the change again (PR description updated accordingly):

  • e077ea6: the step after the joins, computing the relative link target in create_symlink, was still unchecked. With a global bin directory on another branch of the tree the relative form gains a .. per component and can be longer than the absolute target, so a target that the (now checked) joins accept could still overflow rel_buf; bun link aborted with range end index 4198 out of range for slice of length 4096 on the current release too, it is not new to this PR. It now computes into a heap buffer when the upper bound does not fit and lets symlink(2) report ENAMETOOLONG. New test bun link with a link target longer than the path buffer covers both a bin directory for which the bound is pessimistic (linked, link target checked) and one for which the target really does not fit (ENAMETOOLONG, exit 1).
  • 6aecc30: the restructured candidate loop in resolve_bin_target only runs for native binlink redirects, which none of the earlier tests used. The altpath fixtures get a 4.0.0 shape whose parent bin value is 8 KiB, so the first candidate cannot be built and the bin has to come from <platform package>/<bin name>; only the new tarballs and manifest entries are added. Panics on the current release with both linkers, passes here. I did not add a long-value variant of the fallback fixture: the None branches in the callers are covered by the non-redirect tests and the retry itself by the existing fallback tests.

Comment thread test/cli/install/bun-install-registry.test.ts
Same XFS limit as before: the depth now goes into the global directory,
which both the bin directory and the target share, so the link that is
meant to be created has a 765 byte target while the link itself is still
20 bytes below the limit.
@robobun

robobun commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator Author

eecb876 fixes the one CI failure from the previous push (the review above spotted the same thing): the new bun link test created a link with a ~4 kB target, which XFS on the Alpine lanes refuses. The depth is now in the global directory, shared by the bin directory and the target, so the created link has a 765 byte target while everything the test is about (absolute target 20 bytes below the limit, pessimistic bound, far bin directory overflowing) is unchanged. The remaining failures in that build were flaky tests unrelated to this change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant