Skip to content

Conversation

@birkskyum
Copy link
Member

@birkskyum birkskyum commented Nov 24, 2025

Update to the latest RC. A lot has been improved since the 2.0.0-beta.4

Summary by CodeRabbit

  • Chores

    • Bumped core server dependency to a newer release-candidate for improved stability and compatibility.
  • Bug Fixes

    • Standardized response access to use the official response object, improving consistency and reducing silent mismatches.
    • Adjusted error fallback behavior when a response is missing, which may now surface issues that were previously suppressed.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 25, 2025

Walkthrough

Bumped h3 dependency in packages/start-server-core/package.json; getResponse() now returns event.res instead of event._res; response property accesses in server-functions-handler were changed from optional-chained (response?.status) to direct (response.status), altering fallback/error access behavior. No exported signatures changed.

Changes

Cohort / File(s) Summary
Dependency Version Bump
packages/start-server-core/package.json
h3 dependency updated from npm:h3@2.0.0-beta.4 to npm:h3@2.0.1-rc.5.
Request/Response Access Change
packages/start-server-core/src/request-response.ts
getResponse() now returns event.res (was event._res). No signature changes.
Response Property Accesses
packages/start-server-core/src/server-functions-handler.ts
Replaced optional chaining on response properties (e.g., response?.status, response?.statusText) with direct property access (response.status, response.statusText) in multiple Response construction and error-fallback sites. This may change behavior when response is undefined.

Sequence Diagram(s)

sequenceDiagram
  participant Caller as Caller
  participant ReqResp as getResponse()
  participant Event as event

  rect rgb(230,245,255)
    Note left of Caller: Old getResponse flow
    Caller->>ReqResp: call getResponse()
    ReqResp->>Event: read event._res
    Event-->>ReqResp: returns _res (possibly undefined)
    ReqResp-->>Caller: returns _res
  end

  rect rgb(240,255,230)
    Note left of Caller: New getResponse flow
    Caller->>ReqResp: call getResponse()
    ReqResp->>Event: read event.res
    Event-->>ReqResp: returns res (may differ from _res)
    ReqResp-->>Caller: returns res
  end
Loading
sequenceDiagram
  participant Handler as server-functions-handler
  participant ResponseObj as response (may be undefined)

  rect rgb(230,245,255)
    Note left of Handler: Old error/fallback handling (lenient)
    Handler->>ResponseObj: access response?.status / response?.statusText
    ResponseObj-->>Handler: returns status/statusText or undefined (no throw)
    Handler-->Caller: constructs Response with possibly undefined fields
  end

  rect rgb(255,240,230)
    Note left of Handler: New error/fallback handling (strict)
    Handler->>ResponseObj: access response.status / response.statusText
    alt response defined
      ResponseObj-->>Handler: returns values
      Handler-->Caller: constructs Response
    else response undefined
      ResponseObj--x Handler: property access throws TypeError
      Handler-->Caller: error/exception path
    end
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–30 minutes

  • Mixed changes: dependency bump, single-line return change, and multiple direct-access edits that can affect error handling.
  • Files to review closely:
    • packages/start-server-core/src/server-functions-handler.ts — ensure response is always defined where properties are now accessed directly; validate error/fallback behavior.
    • packages/start-server-core/src/request-response.ts — ensure callers expect event.res vs _res.
    • Any callers of getResponse() or server-functions-handler across the repo to confirm compatibility.

Possibly related PRs

Poem

🐇 I hopped through code with nimble paws,

Swapped _res to res with little pause.
Pushed h3 forward, neat and spry,
Watched the handlers reach or try.
— a rabbit’s quiet code-time pause 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Title check ⚠️ Warning The title 'chore: bump h3-v2 to 2.0.1-rc.5' accurately describes the main change in the package.json dependency update, but the PR also includes behavioral changes to request-response.ts and server-functions-handler.ts that go beyond the stated dependency bump objective. Update the title to reflect all significant changes, such as 'chore: bump h3-v2 and fix response handling' or provide clarification on whether non-dependency changes are intentional.
✅ Passed checks (2 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chore--bump-h3-v2-to-2.0.1-rc.5

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@nx-cloud
Copy link

nx-cloud bot commented Nov 25, 2025

View your CI Pipeline Execution ↗ for commit 5de9e24

Command Status Duration Result
nx affected --targets=test:eslint,test:unit,tes... ✅ Succeeded 6m 38s View ↗
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 23s View ↗

☁️ Nx Cloud last updated this comment at 2025-11-25 00:17:25 UTC

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6e0de0a and 1e617ee.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (1)
  • packages/start-server-core/package.json (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-02T16:16:24.898Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5732
File: packages/start-client-core/src/client/hydrateStart.ts:6-9
Timestamp: 2025-11-02T16:16:24.898Z
Learning: In packages/start-client-core/src/client/hydrateStart.ts, the `import/no-duplicates` ESLint disable is necessary for imports from `#tanstack-router-entry` and `#tanstack-start-entry` because both aliases resolve to the same placeholder file (`fake-start-entry.js`) in package.json during static analysis, even though they resolve to different files at runtime.

Applied to files:

  • packages/start-server-core/package.json
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Test
  • GitHub Check: Preview

"@tanstack/start-client-core": "workspace:*",
"@tanstack/start-storage-context": "workspace:*",
"h3-v2": "npm:h3@2.0.0-beta.4",
"h3-v2": "npm:h3@2.0.1-rc.5",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify h3@2.0.1-rc.5 compatibility before merging.

The dependency bump from 2.0.0-beta.4 to 2.0.1-rc.5 moves to a release candidate with a patch version increment. Ensure that:

  1. The new version exists and is available on npm
  2. No breaking changes are introduced in the rc version
  3. All existing tests pass with the bumped dependency

🌐 Web query:

What are the breaking changes or migration steps for h3 v2.0.1-rc.5 compared to v2.0.0-beta.4?

💡 Result:

Short summary of changes from v2.0.0-beta.4 → v2.0.1-rc.5 and migration steps

Key breaking change

  • HTTPResponse API changed in v2.0.1-rc.5 (listed as the only explicitly flagged breaking change). You must audit any code that constructs/inspects HTTPResponse objects and update to the new shape/behaviour. [1]

Other notable changes (non-breaking but may require attention)

  • New/exported util: toMiddleware — you can now convert H3 handlers to middleware (exported in the package). Consider replacing custom adapter code with toMiddleware where appropriate. [1]
  • Fixes that affect behaviour:
    • assertBodySize now disallows having both Content-Length and Transfer-Encoding headers — server/client code that manipulates these headers may need to be adjusted. [1]
    • Adjusted pathname handling for mounted sub-app routed middleware — verify routes when mounting sub-apps. [1]
    • Middleware can now return a 404 Response — check middleware error/return flows if you relied on previous behaviour. [1]

What changed since v2.0.0-beta.4 (items you might already rely on)

  • v2.0.0-beta.4 introduced support for thenable values, HTTPEvent, exported toRequest, chunked cookies, ServerRequestContext/req.context inheritance and event-stream comment support — make sure your code is compatible with those v2 beta APIs before applying rc.5. [2]

Concrete migration steps

  1. Read the v2 migration guidance and ensure runtime requirements (ESM, Node >= 20.x or compatible runtime). Update Node if needed. [3][2]
  2. Update package to v2.0.1-rc.5 and run your test-suite (unit + integration). Fix any failing tests that touch responses or middleware.
  3. Audit all usages that construct/return/inspect HTTPResponse objects and update to the new API/shape (see changelog entry "HTTPResponse"). Run integration tests that exercise response headers/body/streams. [1]
  4. If you mount sub-apps or use custom middleware adapters, verify pathnames and consider replacing adapters with the exported toMiddleware util where helpful. [1]
  5. Check code that manipulates Content-Length / Transfer-Encoding headers (and any body-size assertions) to avoid sending both. [1]
  6. Verify middleware return handling (404s allowed) and any code that assumed middleware could not return Response objects. [1]
  7. Run end-to-end tests and smoke test your routes, cookies (chunked cookies support), event streams, and any features introduced in beta.4 to ensure compatibility. [2]

Sources

  • Changelog entry for v2.0.1-rc.5 (includes breaking-change note for HTTPResponse, toMiddleware export, fixes). [1]
  • v2.0.0-beta.4 changelog summary (features introduced in beta.4). [2]
  • v2 migration guide / requirements (ESM, Node versions, web-standards changes). [3]

If you want, I can fetch the exact HTTPResponse diff/PR (#1212) and show specific code changes you must make.


The web search confirms there is a breaking change in v2.0.1-rc.5. The HTTPResponse API has changed, which requires code audits. Let me search the codebase to determine if this affects the code being changed.




🏁 Script executed:

#!/bin/bash
# Search for HTTPResponse usage in packages/start-server-core
rg -n "HTTPResponse" packages/start-server-core --type=ts --type=js --type=json -C3

Length of output: 0


🏁 Script executed:

#!/bin/bash
# Search for h3 imports and usage to understand h3 API surface in use
rg -n "from\s+['\"]h3['\"]|import.*h3" packages/start-server-core --type=ts --type=js -C2

Length of output: 0


🏁 Script executed:

#!/bin/bash
# Check if there are tests for h3 functionality
fd -e "test\.(ts|js)$|spec\.(ts|js)$" packages/start-server-core | head -20

Length of output: 409


🏁 Script executed:

#!/bin/bash
# Look at the actual changes in the PR to see what code touches h3
git diff HEAD~1 packages/start-server-core --stat

Length of output: 60


🏁 Script executed:

#!/bin/bash
# Verify h3 v2.0.1-rc.5 exists on npm
npm view h3@2.0.1-rc.5 | head -20

Length of output: 723


Let me refine the searches with corrected syntax:


---

🏁 Script executed:

```shell
#!/bin/bash
# Check what files exist in packages/start-server-core
fd . packages/start-server-core --type f | grep -E "\.(ts|js|json)$" | head -30

Length of output: 1005


🏁 Script executed:

#!/bin/bash
# Look at git diff with correct syntax
git diff --stat HEAD~1 -- packages/start-server-core

Length of output: 94


🏁 Script executed:

#!/bin/bash
# Search for h3-v2 alias usage in the codebase
rg -n "h3-v2" --type=ts --type=js --type=json -C2

Length of output: 798


🏁 Script executed:

#!/bin/bash
# Check the full package.json to see dependencies and what uses h3
cat packages/start-server-core/package.json | grep -A50 '"dependencies"'

Length of output: 422


🏁 Script executed:

#!/bin/bash
# Search more broadly for h3 or http response handling in src files
fd . packages/start-server-core/src --type f 2>/dev/null | head -20

Length of output: 824


Now let me check what h3 APIs are actually being used in the codebase:


---

🏁 Script executed:

```shell
#!/bin/bash
# Get full view of h3-v2 imports and their usage in request-response.ts
cat packages/start-server-core/src/request-response.ts | head -60

Length of output: 1669


🏁 Script executed:

#!/bin/bash
# Search for HTTPResponse, Response, or middleware patterns in the source files
rg -n "HTTPResponse|h3_updateSession|h3_useSession" packages/start-server-core/src --type=ts -A3 -B1

Length of output: 1284


🏁 Script executed:

#!/bin/bash
# Check if any code constructs or inspects Response objects
rg -n "new.*Response|instanceof.*Response|\.body|\.headers" packages/start-server-core/src/request-response.ts -C2

Length of output: 1376


Verify and test h3@2.0.1-rc.5 compatibility—breaking HTTPResponse API change confirmed.

The dependency bump introduces a breaking change: the HTTPResponse API has changed in v2.0.1-rc.5. Your code in packages/start-server-core/src/request-response.ts directly inspects and manipulates HTTPResponse headers through event.res.headers (lines 140, 146, 153, 162–172, 186–188), which may be affected by this API change.

Required actions:

  1. Run your test-suite (unit + integration) with the new version to identify any failing tests that touch responses
  2. Audit all usages that construct/return/inspect HTTPResponse objects and update to the new API/shape
  3. Verify that the headers API calls (set(), get(), delete(), append(), keys()) still work as expected with the new HTTPResponse shape

The version bump from beta to rc is positive, but cannot merge without confirming compatibility through testing.

🤖 Prompt for AI Agents
In packages/start-server-core/package.json around line 82 we bumped h3 to
2.0.1-rc.5 which introduces a breaking change to the HTTPResponse shape; audit
and test packages/start-server-core/src/request-response.ts (inspect lines ~140,
146, 153, 162–172, 186–188) where code directly accesses event.res.headers and
calls set/get/delete/append/keys: run the full unit and integration test-suite
with the new h3 version, locate failing tests that touch responses, update all
places that construct/return/inspect HTTPResponse objects to the new API shape
(replace direct event.res.headers access with the official h3 v2 accessor
methods or wrappers), and verify each header operation
(set/get/delete/append/keys) is invoked via the new API or a compatibility shim
so tests pass before merging.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Nov 25, 2025

More templates

@tanstack/arktype-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/arktype-adapter@5959

@tanstack/directive-functions-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/directive-functions-plugin@5959

@tanstack/eslint-plugin-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/eslint-plugin-router@5959

@tanstack/history

npm i https://pkg.pr.new/TanStack/router/@tanstack/history@5959

@tanstack/nitro-v2-vite-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/nitro-v2-vite-plugin@5959

@tanstack/react-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router@5959

@tanstack/react-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-devtools@5959

@tanstack/react-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-ssr-query@5959

@tanstack/react-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start@5959

@tanstack/react-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-client@5959

@tanstack/react-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-server@5959

@tanstack/router-cli

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-cli@5959

@tanstack/router-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-core@5959

@tanstack/router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools@5959

@tanstack/router-devtools-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools-core@5959

@tanstack/router-generator

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-generator@5959

@tanstack/router-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-plugin@5959

@tanstack/router-ssr-query-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-ssr-query-core@5959

@tanstack/router-utils

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-utils@5959

@tanstack/router-vite-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-vite-plugin@5959

@tanstack/server-functions-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/server-functions-plugin@5959

@tanstack/solid-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router@5959

@tanstack/solid-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router-devtools@5959

@tanstack/solid-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router-ssr-query@5959

@tanstack/solid-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start@5959

@tanstack/solid-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-client@5959

@tanstack/solid-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-server@5959

@tanstack/start-client-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-client-core@5959

@tanstack/start-plugin-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-plugin-core@5959

@tanstack/start-server-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-server-core@5959

@tanstack/start-static-server-functions

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-static-server-functions@5959

@tanstack/start-storage-context

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-storage-context@5959

@tanstack/valibot-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/valibot-adapter@5959

@tanstack/virtual-file-routes

npm i https://pkg.pr.new/TanStack/router/@tanstack/virtual-file-routes@5959

@tanstack/zod-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/zod-adapter@5959

commit: 5de9e24

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5757084 and 5de9e24.

📒 Files selected for processing (1)
  • packages/start-server-core/src/server-functions-handler.ts (4 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Preview
  • GitHub Check: Test
🔇 Additional comments (1)
packages/start-server-core/src/server-functions-handler.ts (1)

224-225: Now let me examine the actual code context in the server-functions-handler.ts file:

Based on my verification of the h3 v2.0.1-rc.5 documentation and source code:

The optional chaining removal is safe and intentional.

H3Event carries incoming request, prepared response and context, with each HTTP request having h3 internally create an H3Event object and pass it through event handlers. The H3Event constructor assigns res via this.node = { req, res } with a getter get res() { return this.node.res; }, making event.res guaranteed to be present in all properly-initialized events.

The h3 documentation directly accesses event.res.status, event.res.statusText, and event.res.headers without any null checks, confirming that event.res is never nullable in h3 v2.

Since getResponse() simply returns event.res and the h3 framework guarantees this property is always initialized, removing the optional chaining is correct.

Comment on lines +304 to +305
status: response.status ?? 500,
statusText: response.statusText,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Inconsistent error handling - status fallback without response null check.

Line 304 has response.status ?? 500 which provides a fallback for the status value, but without optional chaining on response itself, this will throw a TypeError if getResponse() returns undefined/null (before the ?? 500 check is reached). Line 305 also accesses response.statusText directly without any fallback.

This is inside the error handler (catch block), so defensive coding would be especially valuable here. If getResponse() is guaranteed to return a non-null object, the ?? 500 suggests you expect response.status itself might be undefined, which would be valid. Otherwise, consider using response?.status ?? 500 and response?.statusText for consistency.

Apply this diff if defensive handling is desired:

-        status: response.status ?? 500,
-        statusText: response.statusText,
+        status: response?.status ?? 500,
+        statusText: response?.statusText,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
status: response.status ?? 500,
statusText: response.statusText,
status: response?.status ?? 500,
statusText: response?.statusText,
🤖 Prompt for AI Agents
In packages/start-server-core/src/server-functions-handler.ts around lines
304-305, the catch block currently reads response.status ?? 500 and
response.statusText which will throw if response is null/undefined; update both
accesses to use optional chaining on response (e.g. response?.status ?? 500) and
provide a safe fallback for statusText (e.g. response?.statusText ?? '<no
statusText>') so the error handler is defensive against a missing response.

@birkskyum birkskyum merged commit 97afc67 into main Nov 25, 2025
6 checks passed
@birkskyum birkskyum deleted the chore--bump-h3-v2-to-2.0.1-rc.5 branch November 25, 2025 00:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants