Your AI coding agent reads params the old way, and Next.js 15 warns that it must be awaited

AI coding agents write params.id and cookies().get() the way Next.js 14 allowed. In Next 15 those dynamic APIs are async, so you get a warning or a build error. Here is the mechanism from the Next.js docs, the one-line await fix, and the codemod.

מעבר לתיקון
בעמוד הזה

You asked your AI coding agent for a product page at app/products/[id]/page.js. It wrote params.id the way every tutorial does, and the page even loads. But the terminal prints a warning about params needing to be awaited, and in some setups the build stops on it. The code looks right, and a year ago it was right.

The cause is a change in Next.js 15, and the fix is a single await.

Why this happens

In Next 15, the Next.js docs say, a group of “dynamic APIs” became asynchronous. They are:

  • The params and searchParams props given to pages, layouts, metadata APIs and route handlers
  • cookies(), draftMode() and headers() from next/headers

Before Next 15 you could read params.id directly. Now params is a Promise. Agents learned from a lot of Next 13 and 14 code, so they keep writing the old synchronous form, and the framework warns you about it.

The docs also point out that enumerating these values counts as direct access: {...params}, Object.keys(params), [...headers()] and for (const cookie of cookies()) all trigger the same warning.

How to tell if this is your problem

  1. Check your version. Run npx next --version. If it is 15 or higher, this applies.
  2. Read the warning. It is titled “Dynamic APIs are Asynchronous” in the Next.js docs and points at the file that touched params, searchParams, cookies() or headers().
  3. Open that file and look for params.something or a bare cookies().get(...) with no await.

The fix

In a Server Component, make the function async and await the value. This is the pattern from the Next.js docs:

async function Page({ params }) {
  const { id } = await params
  return <p>ID: {id}</p>
}

The same goes for cookies() and headers(): write const cookieStore = await cookies(), then read from cookieStore.

If the component is a Client Component, it cannot be async. The docs say to unwrap the Promise with React.use():

'use client'
import * as React from 'react'

function Page({ params }) {
  const { id } = React.use(params)
  return <p>ID: {id}</p>
}

Let the codemod do the bulk of it

Next.js ships a codemod for exactly this migration:

npx @next/codemod@canary next-async-request-api .

The docs say it fixes many cases but not all. Where it cannot migrate a call, it leaves a comment starting with @next-codemod-error and a suggested action, such as a helper function that calls cookies() and must become async. Next.js then errors in both dev and build until you handle each one. Make the helper async, await its callers, and remove the comment. If nothing needs doing, you can replace the prefix with @next-codemod-ignore to pass the build.

Do not unwrap too early

The docs add one tip: you can delay awaiting the Promise until you actually need the value. That lets Next.js statically render more of the page. If only one small component needs searchParams, pass the Promise down and await it there, rather than awaiting at the top of the page.

How to avoid this next time

Tell the agent your version up front: “This is Next.js 15 App Router. params, searchParams, cookies() and headers() are async, so await them in Server Components and use React.use() in Client Components.” In review, search the diff for params. and cookies() and check that each one is awaited or unwrapped.

Comments