nodejs/node · error · Error
Query params cannot be passed when url already contains "?"
Error message
Query params cannot be passed when url already contains "?" or "#".
What it means
serializePathWithQuery throws when the input URL string already contains '?' or '#', because appending another serialized query would produce a malformed URL (duplicate '?' or query after fragment). Undici treats this as a programmer error rather than silently merging.
Source
Thrown at deps/undici/src/lib/core/util.js:109
/**
* @param {string} url The path to check for query strings or fragments.
* @returns {boolean} Returns true if the path contains a query string or fragment.
*/
function pathHasQueryOrFragment (url) {
return (
url.includes('?') ||
url.includes('#')
)
}
/**
* @param {string} url The URL to add the query params to
* @param {import('node:querystring').ParsedUrlQueryInput} queryParams The object to serialize into a URL query string
* @returns {string} The URL with the query params added
*/
function serializePathWithQuery (url, queryParams) {
if (pathHasQueryOrFragment(url)) {
throw new Error('Query params cannot be passed when url already contains "?" or "#".')
}
const stringified = stringify(queryParams)
if (stringified) {
url += '?' + stringified
}
return url
}
/**
* @param {number|string|undefined} port
* @returns {boolean}
*/
function isValidPort (port) {
const value = parseInt(port, 10)
return (View on GitHub (pinned to 1b2de5e052)
Solutions
- Drop the query string from the URL and supply all params via queryParams.
- Or drop queryParams and pre-serialize with new URLSearchParams(...).toString() into the URL.
- Use the URL/URLSearchParams APIs to mutate the URL in place rather than concatenating strings.
Example fix
// before
client.request('https://api.example/x?a=1', { query: { b: 2 } })
// after
client.request('https://api.example/x', { query: { a: 1, b: 2 } }) Defensive patterns
Strategy: validation
Validate before calling
function buildUrl(base, query) {
if (query && (base.includes('?') || base.includes('#'))) {
throw new Error('Cannot combine inline query with queryParams object')
}
// proceed with the API call
return query ? `${base}?${new URLSearchParams(query).toString()}` : base
} Prevention
- Pick one source of truth for query params: inline OR object, never both.
- Use URL/URLSearchParams for URL assembly instead of string concatenation.
- Unit-test URL builders for the no-query and with-query cases.
When it happens
Trigger: Passing both a URL with embedded query/fragment AND a queryParams object to an internal helper that calls serializePathWithQuery (the public fetch/request APIs do not surface this directly; it fires through diagnostic, interceptor, or ProxyAgent path-building code).
Common situations: Hand-building URLs with template strings then also passing { query: {...} }; migrating from got/axios where query merging was lenient; double-encoding after a redirect handler that re-applies params.
Related errors
AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13).
Data as JSON: /api/errors/d0101e1cb1b37fb5.
Report an issue: GitHub.