{"record":{"id":"05fd01c6619fdff3","repo":"cypress-io/cypress","slug":"name-should-be-a-single-string-but-got-from-que","errorCode":null,"errorMessage":"name should be a single string but got: ${from.query.name}","messagePattern":"name should be a single string but got: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"packages/app/src/router/router.ts","lineNumber":42,"sourceCode":"\n  /**\n   * Redirect route useful for passing page params when routing to a particular page\n   *\n   * @param name route name\n   * @param params url encoded JSON object of page component params\n   *\n   * @example\n   * // redirects to the Debug page passing a parameter of `from` set to `notification`\n   * \"/redirect?name=Debug&params=%7B%22from%22%3A%22notification%22%7D\"\n   *\n   * @see changeUrlToDebug in packages/server/lib/open_project.ts\n   */\n  routes.push({\n    path: '/redirect',\n    redirect: (from) => {\n      if (from.query.name) {\n        if (typeof from.query.name !== 'string') {\n          throw new Error(`name should be a single string but got: ${from.query.name}`)\n        }\n\n        let params = {}\n\n        if (from.query.params) {\n          if (typeof from.query.params !== 'string') {\n            throw new Error(`params should be a string but got: ${from.query.params}`)\n          }\n\n          try {\n            params = JSON.parse(from.query.params)\n          } catch {\n            throw new Error(`params was not valid JSON: ${from.query.params}`)\n          }\n        }\n\n        return {\n          name: from.query.name,","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/cypress-io/cypress/blob/0d85fdc91230885bca0a91df278312800a48b727/packages/app/src/router/router.ts#L24-L60","documentation":"Thrown by the /redirect route handler in the Cypress app router. The route reads query.name and requires it to be a single string. Express/Vue Router parse repeated query params (?name=A&name=B) into an array, which fails the typeof === 'string' guard. This is a defensive validation on an internal redirect used by changeUrlToDebug in the server.","triggerScenarios":"A client (the server's open_project.ts changeUrlToDebug, or a hand-crafted URL) issues /redirect?name=Debug&name=Runs causing Express to surface name as ['Debug','Runs']. Also reproducible if a buggy caller appends name twice.","commonSituations":"Internal Cypress URL-construction bug that double-appends name, browser extension or proxy mangling query strings, or third-party code linking to /redirect with duplicate params.","solutions":["If you construct the URL, ensure `name` appears exactly once: `/redirect?name=Debug`.","When serializing params from JS, use URLSearchParams with set (not append) for `name`.","Report a Cypress bug if you hit this from normal app navigation — the server should not be emitting duplicate name params."],"exampleFix":"// before\nconst url = `/redirect?name=Debug&name=${secondary}`\n// after\nconst params = new URLSearchParams()\nparams.set('name', 'Debug')\nparams.set('params', JSON.stringify({ from: secondary }))\nconst url = `/redirect?${params.toString()}`","handlingStrategy":"validation","validationCode":"function singleString (v: unknown): string | null {\n  return typeof v === 'string' ? v : null\n}\nconst name = singleString(from.query.name)\nif (!name) throw new Error('name must be a single string')","typeGuard":"function isSingleString (v: unknown): v is string {\n  return typeof v === 'string'\n}","tryCatchPattern":null,"preventionTips":["Use URLSearchParams.set (not append) for the name param.","URL-encode the redirect link before navigating.","Test redirect URLs in CI smoke checks."],"tags":["router","query-validation","internal","app"],"backgroundTag":null,"analyzedSha":"0d85fdc91230885bca0a91df278312800a48b727","analyzedAt":"2026-08-12T16:24:28.056Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}