Error: Route "/orders/[id]" used `params.id`. `params` should be awaited before using its properties.

Next.js · updated 2026-11-03

Logged during rendering in development when a page, layout or route handler reads params, searchParams, cookies() or headers() synchronously. In later Next.js versions the synchronous access stops working, so the warning becomes a real failure.

Error: Route "/orders/[id]" used `params.id`. `params` should be awaited before using its properties.
Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis
    at OrderPage (app/orders/[id]/page.tsx:4:24)

Quick fix

Make the component async and await the value before reading it: const { id } = await params. Do the same for searchParams, cookies() and headers(). In a Client Component, unwrap the promise with React.use(params).

  1. Change the props type: params is a Promise<{ id: string }>, not { id: string }.
  2. Make the page or layout async and write const { id } = await params.
  3. Await cookies() and headers() too: const store = await cookies().
  4. In Client Components, use const { id } = use(params) from react.
  5. Run the official codemod to update many files at once: npx @next/codemod@latest next-async-request-api .
typescript
// app/orders/[id]/page.tsx
type Props = { params: Promise<{ id: string }>; searchParams: Promise<{ tab?: string }> };

export default async function OrderPage({ params, searchParams }: Props) {
  const { id } = await params;
  const { tab = 'details' } = await searchParams;
  const order = await getOrder(id);
  return <OrderView order={order} tab={tab} />;
}

Why it happens

Code written for Next.js 14 or earlier

Before Next.js 15, params and searchParams were plain objects and cookies() returned the store directly. Upgraded apps keep the old synchronous access until each file is updated.

Destructuring in the function signature

export default function Page({ params: { id } }) reads the property synchronously before you can await anything. Destructure after the await instead.

generateMetadata and route handlers

The same rule applies outside pages: generateMetadata({ params }) and route handlers (request, { params }) receive a Promise too, and are easy to miss in an upgrade.

Other fixes

  • TypeScript catches most of these once the props types say Promise, so update the types first and let the compiler list the call sites.
  • Awaiting these values makes the route dynamic; keep them out of components you want statically rendered.

Same error, other wording

  • Error: Route "/" used `searchParams.page`. `searchParams` should be awaited before using its properties.
  • Error: Route "/account" used `cookies().get('session')`. `cookies()` should be awaited before using its value.
  • Error: Route "/api/x" used `headers().get('authorization')`. `headers()` should be awaited before using its value.

Let your coding agent catch the next one

Runheed records this error in production with the stack trace, the breadcrumbs before it and the agent session that shipped the code, and serves it to Claude Code, Cursor or any MCP client. With it connected, you can ask:

> Find the "should be awaited" warnings and errors from our Next.js app, list each file and which dynamic API it reads synchronously, and update them to await params, searchParams, cookies() and headers().

Plans from $29/moSee what your agent readsSee the setupCancel any time from the billing portal

Related errors

References: Next.js docs: sync dynamic APIs (error message), Next.js docs: upgrading to version 15 (async request APIs)