{"record":{"id":"98e197cf340bcbfb","repo":"remix-run/react-router","slug":"route-segment-segment-for-routeid-cannot","errorCode":null,"errorMessage":"Route segment \"${segment}\" for \"${routeId}\" cannot contain \"${char}\".\nIf this is something you need, upvote this proposal for React Router https://github.com/remix-run/react-router/discussions/9822.","messagePattern":"Route segment \"(.+?)\" for \"(.+?)\" cannot contain \"(.+?)\"\\.\nIf this is something you need, upvote this proposal for React Router https://github\\.com/remix-run/react-router/discussions/9822\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/react-router-fs-routes/flatRoutes.ts","lineNumber":363,"sourceCode":"  | \"ESCAPE\"\n  // we hit a `(` and are now in an optional segment until we hit a `)` or an escape sequence\n  | \"OPTIONAL\"\n  // we previously were in a opt fional segment and hit a `[` and are now in an escape sequence until we hit a `]` - take characters literally and skip isSegmentSeparator checks - afterwards go back to OPTIONAL state\n  | \"OPTIONAL_ESCAPE\";\n\nexport function getRouteSegments(routeId: string): [string[], string[]] {\n  let routeSegments: string[] = [];\n  let rawRouteSegments: string[] = [];\n  let index = 0;\n  let routeSegment = \"\";\n  let rawRouteSegment = \"\";\n  let state: State = \"NORMAL\";\n\n  let pushRouteSegment = (segment: string, rawSegment: string) => {\n    if (!segment) return;\n\n    let notSupportedInRR = (segment: string, char: string) => {\n      throw new Error(\n        `Route segment \"${segment}\" for \"${routeId}\" cannot contain \"${char}\".\\n` +\n          `If this is something you need, upvote this proposal for React Router https://github.com/remix-run/react-router/discussions/9822.`,\n      );\n    };\n\n    if (rawSegment.includes(\"*\")) {\n      return notSupportedInRR(rawSegment, \"*\");\n    }\n\n    if (rawSegment.includes(\":\")) {\n      return notSupportedInRR(rawSegment, \":\");\n    }\n\n    if (rawSegment.includes(\"/\")) {\n      return notSupportedInRR(segment, \"/\");\n    }\n\n    routeSegments.push(segment);","sourceCodeStart":345,"sourceCodeEnd":381,"githubUrl":"https://github.com/remix-run/react-router/blob/6beaca39526d5716c3c112ebb0782765baa5a9ce/packages/react-router-fs-routes/flatRoutes.ts#L345-L381","documentation":"getRouteSegments() parses each file-based route id into URL segments and rejects raw segments containing '*' or ':' — literal splat/param characters that React Router does not currently support in segment names. The message points to the GitHub discussion (#9822) proposing support, telling you to rename the file instead. It is a hard parse-time error raised while flatRoutes() builds the manifest.","triggerScenarios":"A route filename whose segment portion contains a literal '*' or ':', e.g. app/routes/docs.v*:slug.tsx or app/routes/schedule.HH:mm.tsx — pushRouteSegment detects the character in the raw segment and throws.","commonSituations":"Trying to hand-write ':param' or '*splat' URL syntax into flat-routes filenames; migrating from another router's file conventions where those characters are meaningful; naming files after time/colon patterns.","solutions":["Rename the file to remove the '*' or ':' characters","Use the supported '$param' convention for dynamic segments instead of ':param'","If you genuinely need the feature, upvote discussion #9822 and restructure routes meanwhile"],"exampleFix":"# before\napp/routes/docs.v*:slug.tsx\n\n# after\napp/routes/docs.$version.$slug.tsx","handlingStrategy":"validation","validationCode":"// reject offending filenames before the route manifest is built\nimport path from \"node:path\";\nfor (const file of routeFiles) {\n  for (const seg of path.basename(file).split(\".\")) {\n    if (seg.includes(\":\") || seg.includes(\"*\")) {\n      throw new Error(`Rename ${file}: segment '${seg}' contains ':' or '*'`);\n    }\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use the $param convention for dynamic segments — never :param or *splat in filenames","Add a filename lint step for the routes directory","Watch discussion #9822 if you need literal : or * segments"],"tags":["file-routing","fs-routes","route-segment","naming","filename"],"backgroundTag":"invalid-route-segment","analyzedSha":"6beaca39526d5716c3c112ebb0782765baa5a9ce","analyzedAt":"2026-08-18T18:04:14.938Z","contentChangedAt":"2026-08-18T18:04:14.938Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}