fix: do not await writeEarlyHints callback in Node.js#1387
Conversation
In Node.js v24, res.writeEarlyHints() does not call the callback when passed an empty hints object, causing the returned Promise to never resolve and the request handler to hang indefinitely. Since early hints are fire-and-forget by nature, we now call writeEarlyHints without wrapping it in a Promise. Fixes h3js#1383
📝 WalkthroughWalkthrough
ChangesNode.js Early Hints Fast Path
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint skipped: no ESLint configuration detected in root package.json. To enable, add Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/utils/response.ts (1)
111-114: 💤 Low valueConsider simplifying return type to
void.Since both the native and fallback code paths now return
voidsynchronously (no path returnsPromise<void>after removing the Promise wrapper), the return type annotation could be simplified fromvoid | Promise<void>to justvoidfor clarity.♻️ Simplify return type
export function writeEarlyHints( event: H3Event, hints: Record<string, string | string[]>, -): void | Promise<void> { +): void {🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/utils/response.ts` around lines 111 - 114, The writeEarlyHints function's annotated return type (void | Promise<void>) is outdated because both native and fallback code paths now return synchronously; update the signature to return just void by changing the type annotation on writeEarlyHints and any related overloads/usages (referencing writeEarlyHints and H3Event) so the function signature and callers reflect a synchronous void return.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@src/utils/response.ts`:
- Around line 111-114: The writeEarlyHints function's annotated return type
(void | Promise<void>) is outdated because both native and fallback code paths
now return synchronously; update the signature to return just void by changing
the type annotation on writeEarlyHints and any related overloads/usages
(referencing writeEarlyHints and H3Event) so the function signature and callers
reflect a synchronous void return.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: e74757b7-0168-4c56-8f07-e17f4331c326
📒 Files selected for processing (1)
src/utils/response.ts
Fixes #1383
Problem
In Node.js v24, does not call the callback when passed an empty hints object (or possibly in other cases). This causes the returned Promise to never resolve, and the request handler hangs indefinitely.
Root Cause
The original code wrapped in a Promise:
If the callback is never called, the Promise never resolves.
Fix
Since early hints are fire-and-forget by nature, we now call without wrapping it in a Promise:
This prevents the handler from hanging while still sending the early hints.
Summary by CodeRabbit