[GH-ISSUE #443] fix: can't use next/headers in server action and route #99

Closed
opened 2026-05-06 12:37:12 +02:00 by BreizhHardware · 4 comments

Originally created by @bestyxie on GitHub (Mar 11, 2026).
Original GitHub issue: https://github.com/cloudflare/vinext/issues/443

always caught an error: headers() can only be called from a Server Component, Route Handler, or Server Action. Make sure you're not calling it from a Client Component.

But I do use it in server action and route handler. now the only way I could use it is Server Component.

Originally created by @bestyxie on GitHub (Mar 11, 2026). Original GitHub issue: https://github.com/cloudflare/vinext/issues/443 always caught an error: headers() can only be called from a Server Component, Route Handler, or Server Action. Make sure you're not calling it from a Client Component. But I do use it in server action and route handler. now the only way I could use it is Server Component.
Author
Owner

@Divkix commented on GitHub (Mar 11, 2026):

I checked the current App Router request path in main, and both route handlers and server actions are already executed under the same request headers/cookies context, so this is not an obvious framework bug from code inspection alone. Route handlers also already have compat coverage for next/headers.

What I don’t see yet is a minimal reproduction for headers() specifically inside a server action. Could you share a small repro repo or the exact server action / route handler code that fails, plus whether this happens in dev, build, or both? If you can provide that, we can confirm whether this is a real vinext bug or a usage-specific issue and add a regression test.

<!-- gh-comment-id:4040431641 --> @Divkix commented on GitHub (Mar 11, 2026): I checked the current App Router request path in main, and both route handlers and server actions are already executed under the same request headers/cookies context, so this is not an obvious framework bug from code inspection alone. Route handlers also already have compat coverage for next/headers. What I don’t see yet is a minimal reproduction for headers() specifically inside a server action. Could you share a small repro repo or the exact server action / route handler code that fails, plus whether this happens in dev, build, or both? If you can provide that, we can confirm whether this is a real vinext bug or a usage-specific issue and add a regression test.
Author
Owner

@ryanbuening commented on GitHub (Mar 11, 2026):

I might have a similar issue. Something in 0.0.27 caused issues with next/headers where it loses the correct this binding during iteration. It results in "TypeError: Illegal invocation". I'm using the function below as a workaround:

export async function getSafeHeaders() {
  const rawHeaders = await headers();
  const safeHeaders = new Headers();
  rawHeaders.forEach((value, key) => {
    safeHeaders.append(key, value);
  });
  return safeHeaders;
}
<!-- gh-comment-id:4042925037 --> @ryanbuening commented on GitHub (Mar 11, 2026): I might have a similar issue. Something in 0.0.27 caused issues with `next/headers` where it loses the correct `this` binding during iteration. It results in "TypeError: Illegal invocation". I'm using the function below as a workaround: ```ts export async function getSafeHeaders() { const rawHeaders = await headers(); const safeHeaders = new Headers(); rawHeaders.forEach((value, key) => { safeHeaders.append(key, value); }); return safeHeaders; } ```
Author
Owner

@Divkix commented on GitHub (Mar 12, 2026):

Thanks, I tracked down the TypeError: Illegal invocation report and that one is a real bug on our side.

The issue was in the next/headers shim: the lazy request-backed Headers proxy was returning Symbol.iterator unbound, so iterator-based usage like Array.from(headers()), [...headers()], or Object.fromEntries(headers()) could fail even though forEach() worked.

I opened a fix here: https://github.com/cloudflare/vinext/pull/480

That PR also adds regression coverage for:

  • iterator-based headers() access in the shim
  • iterator-based headers() access in a real App Router route handler

So the workaround of copying into a fresh Headers object should no longer be needed once that lands.

Separately, this looks different from the original issue body (headers() can only be called from a Server Component, Route Handler, or Server Action). I still can’t reproduce that specific failure on current main, and route handlers / server actions already run with the request headers context in code. If you’re still hitting that original error, please share a minimal repro or the exact route handler / server action code, and whether it happens in dev, build, or both

<!-- gh-comment-id:4043102240 --> @Divkix commented on GitHub (Mar 12, 2026): Thanks, I tracked down the `TypeError: Illegal invocation` report and that one is a real bug on our side. The issue was in the `next/headers` shim: the lazy request-backed `Headers` proxy was returning `Symbol.iterator` unbound, so iterator-based usage like `Array.from(headers())`, `[...headers()]`, or `Object.fromEntries(headers())` could fail even though `forEach()` worked. I opened a fix here: https://github.com/cloudflare/vinext/pull/480 That PR also adds regression coverage for: - iterator-based `headers()` access in the shim - iterator-based `headers()` access in a real App Router route handler So the workaround of copying into a fresh `Headers` object should no longer be needed once that lands. Separately, this looks different from the original issue body (`headers() can only be called from a Server Component, Route Handler, or Server Action`). I still can’t reproduce that specific failure on current `main`, and route handlers / server actions already run with the request headers context in code. If you’re still hitting that original error, please share a minimal repro or the exact route handler / server action code, and whether it happens in dev, build, or both
Author
Owner

@bestyxie commented on GitHub (Mar 13, 2026):

I upgraded the vinext version from 0.0.21 to 0.0.29, problem solved.

<!-- gh-comment-id:4053094683 --> @bestyxie commented on GitHub (Mar 13, 2026): I upgraded the vinext version from 0.0.21 to 0.0.29, problem solved.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/vinext#99
No description provided.