---
title: "Synchronous cookies()/headers()/draftMode() (next/sync-dynamic-api)"
description: "These return Promises since Next.js 15, and synchronous access was removed in 16: the property read happens on a Promise."
url: http://localhost:4173/rules/next/sync-dynamic-api
updated: 2026-11-11
---

# Synchronous cookies()/headers()/draftMode()

> `next/sync-dynamic-api` is a vetd rule. It flags: Synchronous cookies()/headers()/draftMode(). It runs on every `check`, together with the TypeScript check.

| Fact | Value |
| --- | --- |
| Rule id | `next/sync-dynamic-api` |
| Severity | not set |
| Group | Next.js 16 upgrade |
| Tags | nextjs-16, correctness |

## Why it matters

These return Promises since Next.js 15, and synchronous access was removed in 16: the property read happens on a Promise.

## How to fix it

Await first: `(await cookies()).get("name")`.

## Credit

Based on work by:

- [Next.js team](https://nextjs.org): Made cookies(), headers() and draftMode() asynchronous in Next.js 15 and removed synchronous access in 16.

## References

- [cookies](https://nextjs.org/docs/app/api-reference/functions/cookies), Next.js
- [headers](https://nextjs.org/docs/app/api-reference/functions/headers), Next.js
- [draftMode](https://nextjs.org/docs/app/api-reference/functions/draft-mode), Next.js
- [How to upgrade to version 16](https://nextjs.org/docs/app/guides/upgrading/version-16), Next.js

## See it

Demos in the vetd Lab:

- [Await request APIs](http://localhost:4173/lab/nextjs/await-request-apis)

## Related rules

- [`next/route-params`](http://localhost:4173/rules/next/route-params.md)

## Get this text from vetd

MCP: call `explain` with `{ "diagnosticId": "next/sync-dynamic-api" }`. CLI: `npx vetd explain next/sync-dynamic-api`.

---

[All 92 rules](http://localhost:4173/rules.md) · Previous: [`next/revalidate-tag-profile`](http://localhost:4173/rules/next/revalidate-tag-profile.md) · Next: [`next/no-head-in-app`](http://localhost:4173/rules/next/no-head-in-app.md)
