The Next.js 15 Async Params Pitfall: Why 50% of Projects Break on One Missing await
By Arash Latifi
In Next.js 15 params and searchParams are Promises. Without await the page breaks or goes stale. The correct pattern, common mistakes, and a 30-second fix.
TL;DR: In Next.js 15
paramsandsearchParamsare not plain objects — they arePromises. If you don'tawaitthem, the build breaks or you get stale/undefined values. Seen in 50% of migrations, fixed with a 3-line pattern.
Why async?
Until Next.js 14 this worked:
In Next.js 15 the same code warns at build and params.slug becomes undefined at runtime. Reason: the team made params a Promise for Partial Prerendering and precise caching — right for performance, breaking for everyone.
If you're still busy with the Tailwind v4 migration or image optimization, fix this trap first.
Wrong vs right
❌ Wrong 1: without await
✅ Right: await in server component
❌ Wrong 2: generateMetadata without await
❌ Wrong 3: searchParams in client
30-second migration checklist
Final pattern for every page.tsx / layout.tsx:
When you don't need await
- Client component with
useParams(): TheuseParams()hook fromnext/navigationgives you the resolved value — no await needed. This trap is only for server props. generateStaticParams: It creates and returnsparams— no input.
FAQ
Do I need to make everything async?
Only files that receive params/searchParams. Others can stay sync. But every Page/Layout that takes these props must be async.
Why doesn't TypeScript complain?
If you typed params as any, the error is hidden. Type it as Promise<{ slug: string }> to catch it in tsc.
Does this conflict with Zod form validation?
No — Zod lives in a Server Action. Only if you read params inside that Action do you also need await.
Wrap-up
Next.js 15 added one await to every params to make caching and PPR work. If you see a white page or undefined after upgrading, check this file first. One await saves the whole site.