cypress-io/cypress · warning · Error
params should be a string but got: ${from.query.params}
Error message
params should be a string but got: ${from.query.params} What it means
Thrown by the /redirect route handler when query.params is present but not a string. Same defensive-validation pattern as error 51: query params can be arrays when repeated, and the handler does not know how to JSON.parse an array. The handler then attempts JSON.parse on params, so it requires a string form.
Source
Thrown at packages/app/src/router/router.ts:49
* @example
* // redirects to the Debug page passing a parameter of `from` set to `notification`
* "/redirect?name=Debug¶ms=%7B%22from%22%3A%22notification%22%7D"
*
* @see changeUrlToDebug in packages/server/lib/open_project.ts
*/
routes.push({
path: '/redirect',
redirect: (from) => {
if (from.query.name) {
if (typeof from.query.name !== 'string') {
throw new Error(`name should be a single string but got: ${from.query.name}`)
}
let params = {}
if (from.query.params) {
if (typeof from.query.params !== 'string') {
throw new Error(`params should be a string but got: ${from.query.params}`)
}
try {
params = JSON.parse(from.query.params)
} catch {
throw new Error(`params was not valid JSON: ${from.query.params}`)
}
}
return {
name: from.query.name,
params,
query: {}, //reset query params so they do not get passed on
}
}
return { path: '/' }
},View on GitHub (pinned to 0d85fdc912)
Solutions
- Always JSON.stringify the params object before placing it in the URL: `params.set('params', JSON.stringify(obj))`.
- Ensure params appears only once in the query string.
- If hitting this from Cypress itself, report a bug — the server should always stringify.
Example fix
// before
params.set('params', { from: 'notification' }) // becomes '[object Object]'
// after
params.set('params', JSON.stringify({ from: 'notification' })) Defensive patterns
Strategy: validation
Validate before calling
function asString (v: unknown): string | null {
return typeof v === 'string' ? v : null
}
const params = asString(from.query.params)
if (from.query.params && !params) throw new Error('params must be a string') Type guard
function isSingleString (v: unknown): v is string {
return typeof v === 'string'
} Prevention
- Always JSON.stringify params before URL insertion.
- Use URLSearchParams.set to avoid duplicate keys.
- Unit-test redirect URL construction.
When it happens
Trigger: A caller issues /redirect?...¶ms=A¶ms=B, or a buggy caller passes params as a non-stringified object via URLSearchParams.set with an object that gets toStringed incorrectly. Most commonly an internal code path that forgets to JSON.stringify the params payload before adding it to the URL.
Common situations: Internal Cypress URL construction (changeUrlToDebug) forgetting to JSON.stringify, browser extension duplicating query params, or manual testing of the /redirect endpoint with malformed params.
Related errors
- name should be a single string but got: ${from.query.name}
- params was not valid JSON: ${from.query.params}
- Missing event for ${event}
AI-assisted analysis of cypress-io/cypress@0d85fdc912 (2026-08-12).
Data as JSON: /api/errors/a4862799ba6fc450.
Report an issue: GitHub.