fix(nextjs): ignore response header mutations in GET handlers#209
fix(nextjs): ignore response header mutations in GET handlers#209aqilaziz wants to merge 1 commit into
Conversation
|
Note No issues found |
|
@aqilaziz is attempting to deploy a commit to the Million Team on Vercel. A member of the Team first needs to authorize it. |
9598ea1 to
1ed2336
Compare
| } | ||
| if (object?.type !== "CallExpression" || object.callee?.type !== "Identifier") return false; | ||
| return object.callee.name === "headers"; | ||
| }; |
There was a problem hiding this comment.
Shared findSideEffect suppresses headers() detection across frameworks
Medium Severity
isHeadersFunctionMutationCall matches headers().set/append/delete(...) and silently suppresses it before the existing isCookiesOrHeadersCall(child, "headers") check can flag it. Since findSideEffect is shared with the TanStack Start rule (tanstack-start.ts line 562), this suppression also applies there — where headers() is not the Next.js read-only accessor and could be a user-defined function returning a mutable object. The headers() branch of isCookiesOrHeadersCall is now effectively dead code for all real Headers API methods. The function also has zero test coverage — the test fixture only exercises isHeadersApiMutationCall and isRequestScopedMutationCall.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit 1ed2336. Configure here.
1ed2336 to
bcde713
Compare
|
Rebased/rebuilt this PR onto current What changed in the updated branch:
Verification:
Note: |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
There are 3 total unresolved issues (including 1 from previous review).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit bcde713. Configure here.
| return false; | ||
| if (!isNodeOfType(object, "CallExpression")) return false; | ||
| return isNodeOfType(object.callee, "Identifier") && object.callee.name === "headers"; | ||
| }; |
There was a problem hiding this comment.
isHeadersFunctionMutationCall silently suppresses Next.js headers() side-effect detection
High Severity
isHeadersFunctionMutationCall matches the exact same AST pattern as isCookiesOrHeadersCall(child, "headers") for methods set, append, and delete. Both detect headers().set(...) where headers is a direct function call — which is the Next.js headers() API from next/headers. Because the new skip on line 121 runs before the existing side-effect detection on lines 128–131, calls like headers().set() in GET handlers are now silently ignored instead of being flagged as side effects. The PR intended to suppress only response header mutations (response.headers.set()), not the Next.js request-headers API.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit bcde713. Configure here.
| bindings.add(child.id.name); | ||
| }); | ||
| return bindings; | ||
| }; |
There was a problem hiding this comment.
Scope-blind binding collection causes false suppression across scopes
Low Severity
collectRequestScopedMutationBindings uses walkAst to recurse into the entire handler body — including nested functions and callbacks — collecting binding names into a flat Set without any scope information. If a nested function declares const store = new Map(), the name "store" is added globally. Then isRequestScopedMutationCall will incorrectly suppress an outer-scope store.set(...) where store refers to a completely different binding (e.g., an external KV store), causing a real side effect to go undetected.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit bcde713. Configure here.


Summary
response.headers.set()in GET route side-effect detectionHeaders/Mapmutations created inside the handlerFixes #206.
Testing
pnpm exec vp test run tests/regressions/nextjs-side-effects.test.tspnpm exec tsc --noEmitfrompackages/react-doctorpnpm exec vp lintgit diff --checkNote
Low Risk
Low risk: changes are limited to lint-side-effect heuristics and test fixtures, primarily reducing false positives without affecting runtime behavior.
Overview
Refines
nextjs-no-side-effect-in-get-handlerdetection by teachingfindSideEffectto ignore outbound response header shaping (e.g.response.headers.set/append/deleteandheaders().*mutations) and ignore mutations on request-scoped collections (new Headers/Map/Setcreated within the handler).Adds a Next.js route fixture and a regression test ensuring these patterns no longer produce diagnostics, and includes a patch changeset for
react-doctor.Reviewed by Cursor Bugbot for commit bcde713. Bugbot is set up for automated code reviews on this repo. Configure here.