cypress-io/cypress · warning · Error

params was not valid JSON: ${from.query.params}

Error message

params was not valid JSON: ${from.query.params}

What it means

Thrown by the /redirect route handler inside a try/catch around JSON.parse(from.query.params). The earlier guards ensured params is a string; this error fires when that string is not valid JSON (e.g. '[object Object]', a truncated payload, or hand-typed garbage). The thrown message echoes the offending value for diagnosis.

Source

Thrown at packages/app/src/router/router.ts:55

  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: '/' }
    },
  })

  const router = _createRouter({
    history: createWebHashHistory(),
    routes,
  })

View on GitHub (pinned to 0d85fdc912)

Solutions

  1. Always JSON.stringify the params payload before adding it to the URL.
  2. URL-encode the JSON via URLSearchParams (it will encode for you) so proxies do not break braces.
  3. If the value is empty, omit the params key entirely — the handler treats absence as `params = {}`.
  4. Validate in the caller with JSON.parse before navigating.

Example fix

// before
const url = `/redirect?name=Debug&params=${obj}` // obj.toString() = '[object Object]'
// after
const params = new URLSearchParams({
  name: 'Debug',
  params: JSON.stringify({ from: 'notification' }),
})
const url = `/redirect?${params.toString()}`
Defensive patterns

Strategy: validation

Validate before calling

function parseRedirectParams (raw: string | undefined): Record<string, unknown> {
  if (!raw) return {}
  try { return JSON.parse(raw) }
  catch { throw new Error(`params is not valid JSON: ${raw}`) }
}

const params = parseRedirectParams(typeof from.query.params === 'string' ? from.query.params : undefined)

Type guard

function isJsonString (v: string): boolean {
  try { JSON.parse(v); return true } catch { return false }
}

Try / catch

try {
  params = JSON.parse(rawParams)
} catch (e) {
  // log and degrade gracefully instead of throwing
  console.warn('Ignoring invalid redirect params:', rawParams)
  params = {}
}

Prevention

When it happens

Trigger: A caller stringifies params incorrectly (Object.prototype.toString), URL-encoding mangles the JSON mid-flight, a proxy truncates the query string, or someone hand-edits the URL with non-JSON content.

Common situations: URLSearchParams.set with a non-stringified object, server-side middleware that rewrites query strings, or copy-paste errors when manually constructing redirect URLs.

Related errors


AI-assisted analysis of cypress-io/cypress@0d85fdc912 (2026-08-12). Data as JSON: /api/errors/81b3d6c0ef046e40. Report an issue: GitHub.