AI & Agent Dev Bug Sandbox logo
AI & Agent Dev Bug Sandbox
Back to Radar

Metadata Routes With `Export Const Revalidate` Are Emitted As Static Files In Adapter Output, Dropping Revalidate On Vercel

sitemap.ts (and robots.ts) that export `revalidate` are incorrectly classified as STATIC_FILE in the adapter build output, losing their revalidate value and causing stale content on Vercel. The route is never regenerated and no function is emitted.

highConfidence 85%Next.jsAffected V16.2.0Affected V16.2.11Affected V16.3.3Affected V16.3.5Affected V16.4.0-Canary.38

Origin Analysis

In `packages/next/src/build/adapter/build-complete.ts`, metadata routes matching `isStaticMetadataFile(route)` are unconditionally added to `staticFiles` as STATIC_FILE when a `.body` file exists, and the app routes loop skips them. Neither path checks `prerenderManifest.routes[route].initialRevalidateSeconds`, so the revalidate configuration is ignored.
1. Create a Next.js project with `app/sitemap.ts` exporting `revalidate = 10` and `app/feed.xml/route.ts` exporting `revalidate = 10`. 2. Run `npm install && npm run build` with an adapter enabled (`NEXT_ENABLE_ADAPTER=1` or `adapterPath`). 3. Inspect the adapter's `onBuildComplete` output: `/sitemap.xml` appears as `{type:'STATIC_FILE'}` while `/feed.xml` appears as `{type:'PRERENDER', initialRevalidate:10}`. 4. Deploy to Vercel; `/sitemap.xml` is served from `.vercel/output/static/` and does not revalidate, showing stale content.

Fixing Code Block

Edge Case Audit

This change only affects adapter builds. It does not handle `revalidate = 0` (which should likely be dynamic rather than static) because the condition uses `> 0`; such routes would still be treated as static. If dynamic behavior is required for `revalidate = 0`, additional logic is needed. Rollback: revert this patch or use the workaround `await connection()` in metadata routes. Test on Vercel and with `next start` to ensure parity, especially for metadata routes that share paths with custom route handlers.

Ecosystem Topology