Skip to content

fix: create the cache dir before symlinking the re-warm project at it - #64

Merged
zkochan merged 1 commit into
mainfrom
fix-rewarm-dangling-symlink
Aug 19, 2026
Merged

fix: create the cache dir before symlinking the re-warm project at it#64
zkochan merged 1 commit into
mainfrom
fix-rewarm-dangling-symlink

Conversation

@zkochan

@zkochan zkochan commented Aug 19, 2026

Copy link
Copy Markdown
Member

The re-warm from #63 broke the first run after merge, on pnpm 11:

[ENOTDIR] ENOTDIR: not a directory, mkdir '.../pnpm11/alotta-files/.rewarm/cache'

Why pnpm 11, and why the smoke test missed it

The cache directory is deleted two rows before update, and a manager whose node_modules row is a registry-free no-op — pnpm restores the tree from the lockfile copy inside node_modules/.pnpm — never recreates it. The re-warm's cache symlink then points at nothing, and the warm-up install dies trying to mkdir cache/store through a dangling link.

The pre-merge smoke test ran pnpm 12 and Bun: pnpm 12 reaches the cache through absolute environment paths (PNPM_HOME, PNPM_CONFIG_CACHE_DIR), never touching the symlink, and Bun's re-downloading node_modules row recreates the directory as a side effect. pnpm 11 is the one manager that both goes through the symlink and skips the re-download — exactly the intersection the test didn't cover.

Fix

Create cwd/cache (idempotently) before symlinking at it. Verified by running pnpm 11 through the full real scenario chain against a local pnpr behind the emulated link: it completes, and its update lands at 1.8s against the 7.5s the cold-cache artifact used to charge it — the pnpm 11 column benefits from #63 just as pnpm 12 does.

Also included: when every measuring job fails, the report job's samples directory never comes into existence, and merge-results died with a raw ENOENT scandir instead of its own explanation. A missing directory is the same situation as an empty one and now produces the same "every measuring job must have failed" error.

🤖 Generated with Claude Code

The re-warm broke the weekly run on its first outing, on pnpm 11: the
cache directory is deleted two rows before update, and a manager whose
`node_modules` row is a registry-free no-op — pnpm restores the tree
from the lockfile copy inside it — never recreates it. The re-warm's
`cache` symlink then points at nothing, and the warm-up install dies
with ENOTDIR trying to mkdir its store through a dangling link. The
smoke test missed it because pnpm 12 reaches the cache through absolute
environment paths rather than the symlink, and Bun's re-downloading
`node_modules` row recreates the directory — pnpm 11 is the manager
that goes through the symlink AND skips the re-download. The directory
is now created (idempotently) before the symlink, and the pnpm 11 chain
runs clean end to end: its update lands at 1.8s against the 7.5s the
cold-cache artifact used to charge it.

Also: when every measuring job fails, the report job's samples
directory never comes into existence, and merge-results died with a raw
ENOENT scandir instead of its own explanation. A missing directory is
the same situation as an empty one and now gets the same error.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 19, 2026

Copy link
Copy Markdown

Warning

Review limit reached

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

Next review available in: 11 minutes

Limit details: You’ve used all 2 included reviews currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

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 within each organization.

For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a2719cfc-037e-43e4-92ff-41c906629b4f

📥 Commits

Reviewing files that changed from the base of the PR and between 2d557be and 6b29db7.

📒 Files selected for processing (2)
  • benchmarkFixture.js
  • mergeResults.js

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Prevent dangling re-warm cache links and clarify missing results

🐞 Bug fix 🕐 10-20 Minutes

Grey Divider

AI Description

• Ensure re-warm cache targets exist before symlinking, preventing pnpm 11 warm-up failures.
• Treat missing result samples like empty uploads, returning the intended all-jobs-failed error.
Diagram

graph TD
  subgraph Benchmark
    A["Cache cleanup"] --> B["Create cache"] --> C["Cache symlink"] --> D["Warm install"]
  end
  subgraph Reporting
    E{"Samples exist?"} -->|Yes| F["Merge runs"]
    E -->|No| G["Clear failure"]
  end
Loading
High-Level Assessment

The current approach is appropriate: recursive mkdir is idempotent and avoids a pre-check race before symlink creation, while catching only ENOENT preserves unexpected filesystem failures. Broader abstractions would add complexity without improving these localized paths.

Files changed (2) +18 / -1

Bug fix (2) +18 / -1
benchmarkFixture.jsCreate the cache target before re-warm symlinking +6/-0

Create the cache target before re-warm symlinking

• Recreates the benchmark cache directory idempotently before linking it into the temporary re-warm project. This prevents pnpm 11 from traversing a dangling cache symlink after prior scenarios remove the directory without recreating it.

benchmarkFixture.js

mergeResults.jsHandle missing sample directories as empty results +12/-1

Handle missing sample directories as empty results

• Converts an ENOENT while reading the samples directory into an empty entry list. The existing no-runs validation then emits the intended explanation that all measuring jobs failed, while other filesystem errors still propagate.

mergeResults.js

@zkochan
zkochan merged commit 5d611d9 into main Aug 19, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant