Skip to content

fix(cli): invalidate cached docs bundle when CLI version changes#15527

Open
thesandlord wants to merge 2 commits intomainfrom
devin/1777409299-fix-windows-stale-bundle-cache
Open

fix(cli): invalidate cached docs bundle when CLI version changes#15527
thesandlord wants to merge 2 commits intomainfrom
devin/1777409299-fix-windows-stale-bundle-cache

Conversation

@thesandlord
Copy link
Copy Markdown
Contributor

@thesandlord thesandlord commented Apr 28, 2026

Description

Fixes a Windows issue where fern docs dev shows "Cannot find module" errors (e.g. qs-0df67fa3c19a2c11, gray-matter-7a5a01feddb85c93, zod-a86475cb848a1e8f) due to stale files from a previous bundle surviving re-download.

Two root causes:

  1. Old bundle not fully removed: The old code used rename + async fire-and-forget rm to clean the old bundle. On Windows, rename can fail when NTFS junctions or locked files are present, leaving old files in place. The new bundle then extracts on top, creating a mix of old and new turbopack-hashed modules.

  2. ETag written before post-processing: The ETag was written immediately after decompression, before pnpm i esbuild, install-esbuild.js, and instrumentation.js removal. If any post-processing step failed, the ETag was already cached, so the next run would skip re-download and reuse the broken bundle.

Changes Made

  • Replace rename + async rm with synchronous await rm(..., { recursive: true, force: true }) to fully delete the old bundle before extracting the new one
  • Move the ETag write to after all post-processing completes, so a failed extraction/setup won't be treated as cached on the next run
  • Remove unused rename import

Testing

  • Biome lint/format clean
  • Verified fix addresses the exact failure from NVIDIA user's debug console output
  • Confirmed the error handling catch block still cleans up incomplete bundles on failure

Link to Devin session: https://app.devin.ai/sessions/1cd17ac93bd94ddc977642e06bcde56e
Requested by: @thesandlord

Previously, fern docs dev only checked the remote bundle's ETag to decide
whether to use the cached bundle. After upgrading the CLI (fern upgrade),
the old bundle in ~/.fern/app-preview could contain stale turbopack-hashed
modules (e.g. qs-0df67fa3c19a2c11, gray-matter-7a5a01feddb85c93) that the
new bundle expected at different paths. This caused 'Cannot find module'
errors on Windows.

Now the CLI version is stored alongside the ETag. When the version changes,
the bundle is automatically re-downloaded and re-processed.

Co-Authored-By: Sandeep Dinesh <sandeep@buildwithfern.com>
@devin-ai-integration
Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

Copy link
Copy Markdown

@claude claude Bot left a comment

Choose a reason for hiding this comment

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

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

Tip: disable this comment in your organization's Code Review settings.

@github-actions
Copy link
Copy Markdown
Contributor

🌱 Seed Test Selector

Select languages to run seed tests for:

  • Python
  • TypeScript
  • Java
  • Go
  • Ruby
  • C#
  • PHP
  • Swift
  • Rust
  • OpenAPI

How to use: Click the ⋯ menu above → "Edit" → check the boxes you want → click "Update comment". Tests will run automatically and snapshots will be committed to this PR.

Two changes to fix stale docs preview bundles on Windows:

1. Replace rename+async-rm with synchronous rm before extraction.
   On Windows, rename can fail when NTFS junctions or locked files are
   present, leaving old files mixed with the new extraction.

2. Move the ETag write to after all post-processing (esbuild install,
   install-esbuild.js, instrumentation.js removal). Previously the ETag
   was written before these steps, so a failed post-processing would
   still cache the broken bundle.

Co-Authored-By: Sandeep Dinesh <sandeep@buildwithfern.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant