[PR #324] [MERGED] fix: suppress Invalid hook call warning during layout pre-render probe #480

Closed
opened 2026-05-06 13:08:18 +02:00 by BreizhHardware · 0 comments

📋 Pull Request Information

Original PR: https://github.com/cloudflare/vinext/pull/324
Author: @james-elicx
Created: 3/7/2026
Status: Merged
Merged: 3/7/2026
Merged by: @james-elicx

Base: mainHead: fix/suppress-invalid-hook-call-in-layout-prerender


📝 Commits (2)

  • 57770dd fix: suppress Invalid hook call warning during layout pre-render probe
  • 8548735 refactor: use AsyncLocalStorage to scope hook-warning suppression per-request

📊 Changes

1 file changed (+90 additions, -70 deletions)

View changed files

📝 packages/vinext/src/server/app-dev-server.ts (+90 -70)

📄 Description

Summary

  • The layout pre-render loop (which calls layout components directly to probe for redirect()/notFound() throws) was missing the console.error suppression that the page pre-render loop already had
  • Layout components using use(promise) trigger React's dev-mode resolveDispatcher() check — H === null outside performWork() — producing noisy stderr warnings in tests even though the renders succeed
  • Wraps the layout pre-render loop in a try/finally that silences the expected warning, matching the existing suppression on the page probe

Root Cause

app-dev-server.ts probes each layout component by calling LayoutComp({ params, children: null }) outside React's render cycle. When a layout calls use(getData()), React's resolveDispatcher() finds H === null (the dispatcher is only set inside performWork()) and emits the "Invalid hook call" warning. The page pre-render already suppressed this, but the layout pre-render did not.

Testing

tests/nextjs-compat/app-rendering.test.ts — all 6 active tests pass with no Invalid hook call output on stderr.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/cloudflare/vinext/pull/324 **Author:** [@james-elicx](https://github.com/james-elicx) **Created:** 3/7/2026 **Status:** ✅ Merged **Merged:** 3/7/2026 **Merged by:** [@james-elicx](https://github.com/james-elicx) **Base:** `main` ← **Head:** `fix/suppress-invalid-hook-call-in-layout-prerender` --- ### 📝 Commits (2) - [`57770dd`](https://github.com/cloudflare/vinext/commit/57770dd7c034c8727258a0b4defa373eb1bd24ba) fix: suppress Invalid hook call warning during layout pre-render probe - [`8548735`](https://github.com/cloudflare/vinext/commit/8548735e0f014862c8656bd432e14dbf3c42d6c1) refactor: use AsyncLocalStorage to scope hook-warning suppression per-request ### 📊 Changes **1 file changed** (+90 additions, -70 deletions) <details> <summary>View changed files</summary> 📝 `packages/vinext/src/server/app-dev-server.ts` (+90 -70) </details> ### 📄 Description ## Summary - The layout pre-render loop (which calls layout components directly to probe for `redirect()`/`notFound()` throws) was missing the `console.error` suppression that the page pre-render loop already had - Layout components using `use(promise)` trigger React's dev-mode `resolveDispatcher()` check — `H === null` outside `performWork()` — producing noisy `stderr` warnings in tests even though the renders succeed - Wraps the layout pre-render loop in a `try/finally` that silences the expected warning, matching the existing suppression on the page probe ## Root Cause `app-dev-server.ts` probes each layout component by calling `LayoutComp({ params, children: null })` outside React's render cycle. When a layout calls `use(getData())`, React's `resolveDispatcher()` finds `H === null` (the dispatcher is only set inside `performWork()`) and emits the "Invalid hook call" warning. The page pre-render already suppressed this, but the layout pre-render did not. ## Testing `tests/nextjs-compat/app-rendering.test.ts` — all 6 active tests pass with no `Invalid hook call` output on `stderr`. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
BreizhHardware 2026-05-06 13:08:18 +02:00
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#480
No description provided.