Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/start-server-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
"@tanstack/router-core": "workspace:*",
"@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.

"seroval": "^1.4.0",
"tiny-invariant": "^1.3.3"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/start-server-core/src/request-response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ export function clearSession(config: Partial<SessionConfig>): Promise<void> {
// not public API
export function getResponse() {
const event = getH3Event()
return event._res
return event.res
}

// not public API (yet)
Expand Down
16 changes: 8 additions & 8 deletions packages/start-server-core/src/server-functions-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,8 @@ export const handleServerAction = async ({
return new Response(
nonStreamingBody ? JSON.stringify(nonStreamingBody) : undefined,
{
status: response?.status,
statusText: response?.statusText,
status: response.status,
statusText: response.statusText,
headers: {
'Content-Type': 'application/json',
[X_TSS_SERIALIZED]: 'true',
Expand Down Expand Up @@ -251,8 +251,8 @@ export const handleServerAction = async ({
},
})
return new Response(stream, {
status: response?.status,
statusText: response?.statusText,
status: response.status,
statusText: response.statusText,
headers: {
'Content-Type': 'application/x-ndjson',
[X_TSS_SERIALIZED]: 'true',
Expand All @@ -261,8 +261,8 @@ export const handleServerAction = async ({
}

return new Response(undefined, {
status: response?.status,
statusText: response?.statusText,
status: response.status,
statusText: response.statusText,
})
} catch (error: any) {
if (error instanceof Response) {
Expand Down Expand Up @@ -301,8 +301,8 @@ export const handleServerAction = async ({
)
const response = getResponse()
return new Response(serializedError, {
status: response?.status ?? 500,
statusText: response?.statusText,
status: response.status ?? 500,
statusText: response.statusText,
Comment on lines +304 to +305
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.

headers: {
'Content-Type': 'application/json',
[X_TSS_SERIALIZED]: 'true',
Expand Down
44 changes: 27 additions & 17 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading