Build1 publisher3 min readPublished
Next.js 15 warns instead of failing, so the async params fix keeps getting deferred
Request-scoped values became promises, but pages that read them synchronously still render. A warning that does not break the build is a warning that ships.
The Engineer · Build desk
Drafted by a language model from the sources cited here and checked against its claim ledger before publication. How we use AISend a correction
What happened
- The Next.js error text reads: Route "/blog/[slug]" used params.slug. params should be awaited before using its properties.
- The same warning sometimes appears with searchParams, and sometimes with cookies() or headers().
- Sometimes the page still seems to work while the terminal keeps emitting the warning.
- In Next.js 15+, the Dynamic APIs params, searchParams, cookies(), headers() and draftMode() are asynchronous and should be awaited before their properties are read.
- Five distinct request-dependent APIs are named as asynchronous in Next.js 15+.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
Next.js 15 made a set of request-scoped values asynchronous, and code that still reads them synchronously frequently renders anyway while the terminal repeats a complaint [4][3]. Output that looks correct plus a log line is the least actionable signal a framework can send, and that is exactly why this migration is being postponed rather than done.
The message is specific. It names the route and the property: `Route "/blog/[slug]" used params.slug. params should be awaited before using its properties` [1]. The same class of warning turns up for `searchParams`, and for `cookies()` and `headers()` [2]. According to a dev.to walkthrough of the error, five request-dependent APIs are asynchronous in Next.js 15 and later: `params`, `searchParams`, `cookies()`, `headers()` and `draftMode()` [12][4]. That is five distinct call sites to audit, not one [5]. What they share is that their values change per request: which route was opened, what query string came with it, which cookies and headers arrived, whether draft mode is on [10].
The repair is small, which is part of the problem. Two edits: make the component `async`, then await the whole object before reading off it, as in `const { slug } = await params` [6]. The near miss that looks like a fix is `const slug = await params.slug`, which still reaches for `.slug` before `params` has resolved [7]. And a component cannot await anything until it is declared `async`; JavaScript rejects the rest [8].
Two things make this spread further than a single page file. First, the supply of examples: code written for Next.js 13 or 14 can start emitting warnings or errors immediately after an upgrade [9], so anyone following an older App Router tutorial reproduces the broken shape on a current framework. Second, the walkthrough notes that this shows up often on blog-style sites because the page component is not the only place a route reads `params` [11]. One route can hold several reads, and the compiler will not enumerate them for you.
Treat the current behaviour for what it is: a compatibility shim that renders your synchronous access and files a note. Nothing in that arrangement forces a decision. The build passes, the page paints, the warning scrolls past in a dev server nobody is reading, and the diff that would have cost ten minutes per route becomes a latent failure spread across every dynamic segment, metadata function and cookie read in the app. The terminal is the only inventory the framework hands over, and it is an inventory that disappears when you clear the console.
What to watch is the gap between warning and enforcement. The walkthrough does not state a version at which the message stops being a warning [13], which means the deadline is unknown rather than absent. The practical measure of exposure is not how many routes use dynamic segments but how many separate places each route reads request data [11]; that count is the size of the migration, and it only grows while the framework keeps being polite about it.