Symptom
The _playground-ensure step of just ci / just ci-parallel intermittently
fails its bun install:
bun install v1.3.14 (0d9b296a)
error: Failed to link jsesc: EEXIST
error: recipe `_playground-ensure` failed on line 1307 with exit code 1
ci-parallel: a background gate failed (see above)
Because ci-parallel is the pre-push gate (and a CI job), this aborts the
push. Re-running succeeds — it is a flaky link race in bun's installer, not
a real dependency problem. Observed repeatedly on 2026-06-17 (had to retry the
push twice while landing the CodeQL-advanced and change-aware-gating PRs).
Likely cause
bun's parallel package linker hitting EEXIST when materialising
node_modules (here jsesc) against a warm global cache — a known class of
bun flake on shared/concurrent installs.
Suggested fixes (pick one)
- Pin bun to a known-good version in
mise.toml and pass
bun install --frozen-lockfile in _playground-ensure (deterministic,
no resolution step).
- If the race persists, fall back to
bun install --backend=copyfile
(avoids hardlink/symlink EEXIST at the cost of some speed), or retry the
install once on EEXIST.
- Consider gating
_playground-ensure out of the pre-push path (keep it in
CI only) so a JS-install flake can't block pushing Rust changes.
Low priority / dev-experience, but it's been actively wedging pushes.
Symptom
The
_playground-ensurestep ofjust ci/just ci-parallelintermittentlyfails its
bun install:Because
ci-parallelis the pre-push gate (and a CI job), this aborts thepush. Re-running succeeds — it is a flaky link race in bun's installer, not
a real dependency problem. Observed repeatedly on 2026-06-17 (had to retry the
push twice while landing the CodeQL-advanced and change-aware-gating PRs).
Likely cause
bun's parallel package linker hitting
EEXISTwhen materialisingnode_modules(herejsesc) against a warm global cache — a known class ofbun flake on shared/concurrent installs.
Suggested fixes (pick one)
mise.tomland passbun install --frozen-lockfilein_playground-ensure(deterministic,no resolution step).
bun install --backend=copyfile(avoids hardlink/symlink EEXIST at the cost of some speed), or retry the
install once on EEXIST.
_playground-ensureout of the pre-push path (keep it inCI only) so a JS-install flake can't block pushing Rust changes.
Low priority / dev-experience, but it's been actively wedging pushes.