[remix] Prevent 404 responses from being cached with immutable headers#14828
[remix] Prevent 404 responses from being cached with immutable headers#14828
Conversation
Move cache-control headers for static assets from before `handle: 'filesystem'` to after `handle: 'hit'`. This ensures the immutable cache headers are only applied when a file actually exists, preventing 404 responses from being cached for 1 year. This follows the same pattern used by the Next.js builder, which places cache headers in the 'hit' phase to avoid caching 404s. Fixes: https://linear.app/vercel/issue/BE-415 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: 019a869 The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
📦 CLI Tarball ReadyThe Vercel CLI tarball for this PR is now available! Quick TestYou can test this PR's CLI directly by running: npx https://vercel-k2o2ouq7k.vercel.sh/tarballs/vercel.tgz --helpUse in vercel.jsonTo use this CLI version in your project builds, add to your {
"build": {
"env": {
"VERCEL_CLI_VERSION": "vercel@https://vercel-k2o2ouq7k.vercel.sh/tarballs/vercel.tgz"
}
}
} |
🧪 Unit Test StrategyComparing: Strategy: Affected packages only ✅ Only testing packages that have been modified or depend on modified packages. Affected packages - 2 (5%)
Unaffected packages - 39 (95%)
Results
This comment is automatically generated based on the affected testing strategy |
Prevent 404 responses from being cached by adding immutable headers.
I added a probe to assert that we don't put that cache-control header on the response. Add a unit test as well you think? |
This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated. # Releases ## vercel@50.10.0 ### Minor Changes - feat(cli): Add webhooks command for managing webhooks ([#14789](#14789)) Adds a new `webhooks` command to the Vercel CLI with the following subcommands: - `webhooks ls` - List all webhooks with optional `--format json` output - `webhooks get <id>` - Get details of a specific webhook with optional `--format json` output - `webhooks create <url> --event <event>` - Create a new webhook with specified events - `webhooks rm <id>` - Remove a webhook with `--yes` flag to skip confirmation Webhook event types are fetched dynamically from the OpenAPI spec to stay in sync with the API. - Added experimental services support in the CLI new project flow. When `VERCEL_USE_EXPERIMENTAL_SERVICES=1` is set and a project's `vercel.json` contains `experimentalServices`, the CLI will detect and display the configured services during project setup, automatically selecting the "services" framework preset. ([#14776](#14776)) ### Patch Changes - Improve logsv2 command output format with compact single-line display, text-based level labels, dynamic column widths, and smart date display ([#14767](#14767)) - Skip update check when running on Vercel to prevent unnecessary worker spawning in build container ([#14794](#14794)) - fix --help exit codes for marketplace commands ([#14834](#14834)) - Updated dependencies \[[`687f73cebb6ae1cdd7c7feb0910967de99a17ad6`](687f73c), [`e7c5d5fd41e124ef7314978b351696d130e89917`](e7c5d5f), [`c3104a1ae9dbf9048e08bb2fa85605a95b254876`](c3104a1), [`b029736b4be8dac135bef77283f47e1450faf0a9`](b029736), [`d36c1ad3ddaf9303041e61a0a41d973b02007988`](d36c1ad), [`5b31b133970539986ff9e98013d2c364536bd0b5`](5b31b13)]: - @vercel/next@4.15.21 - @vercel/python@6.5.0 - @vercel/remix-builder@5.5.10 - @vercel/backends@0.0.25 - @vercel/static-build@2.8.28 - @vercel/node@5.5.28 - @vercel/express@0.1.36 ## @vercel/python@6.5.0 ### Minor Changes - vendor Python runtime dependencies ([#14827](#14827)) - Bump vercel-runtime version automatically on its releases ([#14842](#14842)) ## @vercel/python-analysis@0.3.0 ### Minor Changes - initial implementation of Python semantic analysis in Rust ([#14690](#14690)) ## @vercel/backends@0.0.25 ### Patch Changes - Improve handling of cjs/esm interop during imports ([#14798](#14798)) ## @vercel/cervel@0.0.12 ### Patch Changes - Improve handling of cjs/esm interop during imports ([#14798](#14798)) - Updated dependencies \[[`d36c1ad3ddaf9303041e61a0a41d973b02007988`](d36c1ad)]: - @vercel/backends@0.0.25 ## @vercel/express@0.1.36 ### Patch Changes - Updated dependencies \[[`d36c1ad3ddaf9303041e61a0a41d973b02007988`](d36c1ad)]: - @vercel/cervel@0.0.12 - @vercel/node@5.5.28 ## @vercel/fs-detectors@5.7.20 ### Patch Changes - Added experimental services support in the CLI new project flow. When `VERCEL_USE_EXPERIMENTAL_SERVICES=1` is set and a project's `vercel.json` contains `experimentalServices`, the CLI will detect and display the configured services during project setup, automatically selecting the "services" framework preset. ([#14776](#14776)) ## @vercel/functions@3.4.1 ### Patch Changes - Fix InMemoryCache to use JSON serialization for consistency with RuntimeCache ([#14751](#14751)) InMemoryCache now serializes values with `JSON.stringify()` on set and deserializes with `JSON.parse()` on get, matching the behavior of RuntimeCache. This ensures consistent behavior when switching between cache implementations (e.g., in-memory for development, remote for production), particularly for types that don't survive JSON round-trips like `Date`, `Map`, `Set`, and `undefined`. ## @vercel/introspection@0.0.11 ### Patch Changes - Updated dependencies \[[`d36c1ad3ddaf9303041e61a0a41d973b02007988`](d36c1ad)]: - @vercel/backends@0.0.25 ## @vercel/next@4.15.21 ### Patch Changes - Strip routes-manifest.json for determinism ([#14783](#14783)) - Update Next.js adapter version ([#14801](#14801)) ## @vercel/remix-builder@5.5.10 ### Patch Changes - [remix] Prevent 404 responses from being cached with immutable headers ([#14828](#14828)) ## @vercel/python-runtime@0.3.0 ### Minor Changes - vendor Python runtime dependencies ([#14827](#14827)) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Summary
handle: 'filesystem'to afterhandle: 'hit'Background
When cache-control headers were placed BEFORE
handle: 'filesystem', the headers would be applied to all matching requests, including 404s. This caused 404 responses for non-existent assets to be cached for 1 year with immutable headers, making them impossible to fix without cache purging.The correct pattern (used by Next.js) is to place cache headers AFTER
handle: 'hit', which only applies them when a file is found:See: https://github.com/vercel/vercel/blob/main/packages/next/src/server-build.ts#L2748-L2766
Test plan
vercel/packages/next/test/fixtures/01-cache-headers/vercel.json
Lines 18 to 21 in 623e43f
Fixes: https://linear.app/vercel/issue/BE-415
Manual curl of test fixture vs older behavior
🤖 Generated with Claude Code