Skip to content

Conversation

@FEgor04
Copy link
Contributor

@FEgor04 FEgor04 commented Jan 2, 2026

There was a bug when setting headers with setResponseHeaders did not change them. The root cause was that Object.entires returned empty array instead of actual headers. The fix is to use headers.entries() instead.
This PR covers the issue with e2e test and fixes it.

Fixes #5407

Summary by CodeRabbit

  • New Features

    • Global server middleware now supports setting custom response headers via new middleware capabilities.
  • Tests

    • Added test coverage validating response header middleware functionality and behavior.

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 2, 2026

📝 Walkthrough

Walkthrough

This PR fixes an issue where setResponseHeaders and setResponseStatus don't work in global middleware. The fix updates the iteration method in setResponseHeaders from Object.entries() to headers.entries(), adds a new middleware example demonstrating the fix, and includes a test verifying response headers are correctly set.

Changes

Cohort / File(s) Summary
E2E middleware example
e2e/react-start/server-functions-global-middleware/src/start.ts
Introduces headerMiddleware that calls setResponseHeaders() to set X-Header-Middleware: Executed response header; registers alongside existing loggingMiddleware in global middleware configuration.
E2E middleware test
e2e/react-start/server-functions-global-middleware/tests/global-middleware.spec.ts
Adds test suite "Setting response headers in middleware" to verify the x-header-middleware response header is set to Executed on GET / requests.
Core response header iteration fix
packages/start-server-core/src/request-response.ts
Changes setResponseHeaders() to iterate via headers.entries() instead of Object.entries(headers), enabling proper header processing in middleware context.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • #5333: Modifies the same request-response.ts file and changes response header handling to return a Headers object from getResponseHeaders().
  • #5276: Related response header handling changes; sets X_TSS_RAW_RESPONSE header on raw Response objects.

Suggested labels

package: react-start-client, package: start-server-core

Poem

🐰 A hop, a skip, headers now flow,
Through middleware's pathways, no longer too slow,
From entries to iterators, the fix takes its flight,
Global middleware headers now set just right!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main fix: replacing Object.entries with headers.entries() in the setResponseHeaders function.
Linked Issues check ✅ Passed The PR directly addresses the bug in issue #5407 by fixing setResponseHeaders to correctly iterate over Headers instances, and includes a test verifying the fix works.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing the setResponseHeaders bug: the core fix, middleware implementation, and test coverage align with issue #5407.
✨ Finishing touches
  • 📝 Generate docstrings

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 Jan 2, 2026

View your CI Pipeline Execution ↗ for commit f7b6a5a

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

☁️ Nx Cloud last updated this comment at 2026-01-02 21:13:12 UTC

@FEgor04
Copy link
Contributor Author

FEgor04 commented Jan 2, 2026

Didn't notice another PR for that issue. Will close that.

@FEgor04 FEgor04 closed this Jan 2, 2026
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: 0

🧹 Nitpick comments (1)
e2e/react-start/server-functions-global-middleware/src/start.ts (1)

6-11: Remove unused imports.

The imports getResponseHeaders and setResponseHeader are not used anywhere in this file. Only getRequest (used in trackMiddlewareExecution) and setResponseHeaders (used in headerMiddleware) are actually needed.

🔎 Proposed fix to remove unused imports
 import {
   getRequest,
-  getResponseHeaders,
-  setResponseHeader,
   setResponseHeaders,
 } from '@tanstack/react-start/server'
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 038d0dc and f7b6a5a.

📒 Files selected for processing (3)
  • e2e/react-start/server-functions-global-middleware/src/start.ts
  • e2e/react-start/server-functions-global-middleware/tests/global-middleware.spec.ts
  • packages/start-server-core/src/request-response.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript strict mode with extensive type safety for all code

Files:

  • packages/start-server-core/src/request-response.ts
  • e2e/react-start/server-functions-global-middleware/tests/global-middleware.spec.ts
  • e2e/react-start/server-functions-global-middleware/src/start.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Implement ESLint rules for router best practices using the ESLint plugin router

Files:

  • packages/start-server-core/src/request-response.ts
  • e2e/react-start/server-functions-global-middleware/tests/global-middleware.spec.ts
  • e2e/react-start/server-functions-global-middleware/src/start.ts
🧠 Learnings (1)
📚 Learning: 2025-12-24T22:47:44.320Z
Learnt from: schiller-manuel
Repo: TanStack/router PR: 6211
File: e2e/react-start/i18n-paraglide/src/server.ts:6-6
Timestamp: 2025-12-24T22:47:44.320Z
Learning: In TanStack Router projects using `inlang/paraglide-js`, the callback passed to `paraglideMiddleware` should use `() => handler.fetch(req)` (referencing the outer `req`) instead of `({ request }) => handler.fetch(request)`. This is intentional because the router needs the untouched URL to perform its own rewrite logic with `deLocalizeUrl`/`localizeUrl`. The middleware's processed request would delocalize the URL and interfere with the router's rewrite handling.

Applied to files:

  • e2e/react-start/server-functions-global-middleware/src/start.ts
⏰ 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
🔇 Additional comments (4)
packages/start-server-core/src/request-response.ts (1)

211-211: Excellent fix for Headers iteration!

This correctly uses the Headers API's entries() method instead of Object.entries(). The bug occurred because Object.entries(headers) returns an empty array when passed a Headers instance (which is not a plain object), whereas headers.entries() properly iterates over the header entries.

e2e/react-start/server-functions-global-middleware/tests/global-middleware.spec.ts (1)

132-139: Well-structured test for the header middleware fix.

The test appropriately validates that response headers set via setResponseHeaders in middleware are correctly applied. The use of lowercase 'x-header-middleware' in the assertion is correct since HTTP headers are case-insensitive and Playwright normalizes them to lowercase.

e2e/react-start/server-functions-global-middleware/src/start.ts (2)

57-63: Perfect demonstration of the setResponseHeaders fix.

This middleware correctly demonstrates the issue that was fixed: creating a Headers instance and passing it to setResponseHeaders. With the fix in request-response.ts, this now properly iterates the headers using headers.entries().


95-95: LGTM!

The middleware is properly registered and will be executed for all requests, allowing the test to verify that headers are correctly set.

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.

setResponseHeaders and setResponseStatus don't work in global middleware

1 participant