Next.js breaking changes, updated weekly
Every verified Next.js trap in Footgun: changes and behaviors that break code or give wrong results, newest first. Each one has the error you see, the fix, and the date it was last checked. The list updates when the weekly check adds or retires a trap. For the full cause and sources, open the trap, or see all Next.js traps.
fg-0566· added 2026-10-27· last checked 2026-10-27
An admin Route Handler with no auth check inside it is open to anyone who finds the URL
Symptom
A request to an /api/admin route with no cookie returns data or makes a change
Fix
Verify the session and the user's role at the top of every admin Route Handler, returning 401 when there is no session and 403 when the user is not an admin. Keep any proxy check as an extra layer, not the only one.
fg-0563· added 2026-10-27· last checked 2026-10-27
A Next.js route that calls OpenAI or Anthropic with no auth or rate limit lets anyone spend your API credits
Symptom
The AI route answers requests that carry no session cookie
Fix
Check the user's session at the top of the handler and return 401 without one, then apply a per-user or per-IP rate limit and return 429 when it is hit. Also turn on any rate limiting your host provides, and set a hard spend limit with the AI provider as a backstop.
fg-0565· added 2026-10-27· last checked 2026-10-27
A Server Action without its own auth check can be called by anyone, even from a page that redirects strangers
Symptom
An admin page redirects signed-out visitors, but its form action still runs when posted to directly
Fix
Verify authentication and authorization inside every Server Action, or in a server-only data access layer each action calls: get the session, throw if there is none, then check that the user owns or may act on the specific record before changing it.
fg-0564· added 2026-10-27· last checked 2026-10-27
A secret in a NEXT_PUBLIC_ environment variable is copied into the JavaScript every visitor downloads
Symptom
A secret API key, such as an OpenAI, Stripe secret or Supabase secret key, is named NEXT_PUBLIC_ something
Fix
Remove the NEXT_PUBLIC_ prefix from every secret and read it only in server code, such as Route Handlers, Server Actions or Server Components, and have the browser call your server instead. Treat any secret that was ever built with the prefix as leaked and rotate it with its provider.
fg-0297· added 2026-10-15· last checked 2026-10-15
Build fails on Next.js 16 because a parallel route slot has no default.js
Symptom
Missing required default.js file for parallel route at app/@modal
Fix
Add default.tsx to each slot that returns null, or calls notFound() if that is the intended behavior.
fg-0298· added 2026-10-15· last checked 2026-10-15
Build fails with 'encountered the unstable value crypto.randomUUID()' after enabling cacheComponents
Symptom
Route "/account": Next.js encountered the unstable value `crypto.randomUUID()` while prerendering.
Fix
Wrap the part that needs the value in Suspense and call await connection() before the call so it runs per request, or cache it with use cache, or move it into a Client Component.
fg-0301· added 2026-10-15· last checked 2026-10-15
File upload through a Server Action fails with 'Body exceeded 1 MB limit'
Symptom
Error: Body exceeded 1 MB limit.
Fix
Raise serverActions.bodySizeLimit to what you actually need, or upload large files straight to object storage with a presigned URL and send only the key to the action.
fg-0302· added 2026-10-15· last checked 2026-10-15
generateStaticParams returning an empty array fails the build once cacheComponents is on
Symptom
Build error linking to /docs/messages/empty-generate-static-params
Fix
Return at least one real param. Unlisted params are still rendered at request time. Keep the export, because deleting it opts the route out of ISR.
fg-0304· added 2026-10-15· last checked 2026-10-15
next/image quality prop is ignored on Next.js 16 and direct /_next/image?q=90 requests return 400
Symptom
An Image with quality={90} is served at q=75
Fix
List every quality you use in images.qualities.
fg-0305· added 2026-10-15· last checked 2026-10-15
next/image returns 400 '"url" parameter is not allowed' for a localhost or private-network image source
Symptom
"url" parameter is not allowed
Fix
Enable images.dangerouslyAllowLocalIP only in development or on a private network you control, or serve the images from a public host.
fg-0307· added 2026-10-15· last checked 2026-10-15
NEXT_PUBLIC_ variable set at container runtime is ignored and the browser still sees the build-time value
Symptom
process.env.NEXT_PUBLIC_API_URL is undefined in the browser even though the container has it set
Fix
Pass public values as build args and rebuild per environment, or read a server-only variable in a Server Component and hand it to the client as a prop. Dynamic lookups like process.env[name] are not inlined at all.
fg-0309· added 2026-10-15· last checked 2026-10-15
params.id is undefined after upgrading to Next.js 16 because params and searchParams are Promises
Symptom
params.slug is undefined in a page that worked on Next.js 14
Fix
Await the prop in Server Components and unwrap it with React.use() in Client Components. Run the async request API codemod, since the general upgrade codemod skips it.
fg-0310· added 2026-10-15· last checked 2026-10-15
redirect() in a Server Action does nothing, or logs NEXT_REDIRECT, when it sits inside try/catch
Symptom
Error: NEXT_REDIRECT
Fix
Call redirect() after the try/catch block, or rethrow framework errors at the top of the catch with unstable_rethrow.
fg-0306· added 2026-10-15· last checked 2026-10-15
Next.js 16 warns middleware is deprecated, and proxy.ts throws if you set runtime = 'edge'
Symptom
The "middleware" file convention is deprecated. Please use "proxy" instead.
Fix
Rename the file and the exported function to proxy, drop the runtime export, and rename config flags like skipMiddlewareUrlNormalize. Stay on middleware.ts if you truly need Edge.
fg-0308· added 2026-10-15· last checked 2026-10-15
notFound() returns HTTP 200 instead of 404 when called inside a Suspense boundary or under loading.tsx
Symptom
curl -I on a missing record returns 200 OK while the page shows the not-found UI
Fix
Call notFound() and redirect() before any await that sits under Suspense, or move the check into proxy or next.config redirects. With cacheComponents, set instant = false on the segment so it blocks instead of streaming a shell.
fg-0311· added 2026-10-15· last checked 2026-10-15
With cacheComponents, dropdowns stay open and forms keep old values after navigating away and back
Symptom
A popover opened before navigation is still open on return
Fix
Add explicit resets: close popovers in a useLayoutEffect cleanup, derive dialog open state from the URL, and reset forms in the submit handler.
fg-0299· added 2026-10-15· last checked 2026-10-15
Enabling cacheComponents breaks the build on export const dynamic, revalidate, fetchCache or dynamicParams
Symptom
Route segment config "dynamicParams" is not compatible with `nextConfig.cacheComponents`.
Fix
Delete each export and use the replacement: remove force-dynamic and let Suspense handle it, map revalidate to cacheLife inside use cache, and replace dynamicParams = false with notFound() for unknown params.
fg-0300· added 2026-10-15· last checked 2026-10-15
'Failed to find Server Action' errors when Next.js runs on more than one container or after a deploy
Symptom
Error: Failed to find Server Action "7f3a...". This request might be from an older or newer deployment.
Fix
Build once and run the same artifact everywhere, set the same NEXT_SERVER_ACTIONS_ENCRYPTION_KEY at build time on every build, and set deploymentId so stale clients do a hard reload.
fg-0303· added 2026-10-15· last checked 2026-10-15
next build fails on Next.js 16 with 'This build is using Turbopack, with a webpack config and no turbopack config'
Symptom
This build is using Turbopack, with a `webpack` config and no `turbopack` config.
Fix
Port the webpack rules to the turbopack key, or keep webpack for builds with the --webpack flag until the plugin supports Turbopack.
Have your agent check Next.js changes before it codes