Skip to content

fix(cache): include query in cache key when opts.path is undefined#5081

Merged
mcollina merged 1 commit intonodejs:mainfrom
maruthang:fix/issue-4209-query-in-cache-key
Apr 21, 2026
Merged

fix(cache): include query in cache key when opts.path is undefined#5081
mcollina merged 1 commit intonodejs:mainfrom
maruthang:fix/issue-4209-query-in-cache-key

Conversation

@maruthang
Copy link
Copy Markdown
Contributor

This relates to...

Fixes #4209

Rationale

makeCacheKey in lib/util/cache.js gated the merge of opts.query into the cache key on pathHasQueryOrFragment(opts.path). However, opts.path is optional — callers can dispatch with only origin + query, in which case opts.path is undefined. Calling .includes('?') on undefined threw TypeError: Cannot read properties of undefined (reading 'includes'), so the query was never folded into key.path and requests with differing query strings could collide in the cache (or fail outright).

The fix is a one-line change: check the already-defaulted fullPath (which falls back to '/' when opts.path is missing) instead of the raw opts.path. This keeps the existing behavior for callers that embed the query directly in path, while correctly serialising opts.query into the cache key when path is not provided.

Changes

Guard makeCacheKey's query-merge branch against an undefined opts.path by inspecting the defaulted fullPath, and add a regression test covering the four path/query permutations.

Features

N/A

Bug Fixes

Breaking Changes and Deprecations

None.

Status

makeCacheKey used pathHasQueryOrFragment(opts.path) to decide whether to
merge opts.query into the cached path, but opts.path can be undefined
when a caller supplies only origin+query at dispatch time. In that case
the check threw TypeError ("Cannot read properties of undefined (reading
'includes')"), so the query was never folded into the cache key and
requests with differing queries could collide or the key construction
itself could fail.

Check the already-defaulted fullPath ('/' when opts.path is missing)
instead, so the query is consistently serialised into key.path and
different query strings get separate cache entries regardless of how
path is supplied.

Refs nodejs#4209

Signed-off-by: Maruthan G <maruthang4@gmail.com>
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Apr 20, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.12%. Comparing base (ec60a7c) to head (f230cf2).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5081      +/-   ##
==========================================
+ Coverage   93.10%   93.12%   +0.01%     
==========================================
  Files         110      110              
  Lines       35807    35807              
==========================================
+ Hits        33339    33345       +6     
+ Misses       2468     2462       -6     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

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

lgtm

@mcollina mcollina merged commit 1f57375 into nodejs:main Apr 21, 2026
35 checks passed
mcollina pushed a commit that referenced this pull request Apr 29, 2026
…5081)

makeCacheKey used pathHasQueryOrFragment(opts.path) to decide whether to
merge opts.query into the cached path, but opts.path can be undefined
when a caller supplies only origin+query at dispatch time. In that case
the check threw TypeError ("Cannot read properties of undefined (reading
'includes')"), so the query was never folded into the cache key and
requests with differing queries could collide or the key construction
itself could fail.

Check the already-defaulted fullPath ('/' when opts.path is missing)
instead, so the query is consistently serialised into key.path and
different query strings get separate cache entries regardless of how
path is supplied.

Refs #4209

Signed-off-by: Maruthan G <maruthang4@gmail.com>
(cherry picked from commit 1f57375)
@github-actions github-actions Bot mentioned this pull request May 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

interceptors.cache is not aware of query?

3 participants