{"record":{"id":"04fa2ed2198ddcdf","repo":"anomalyco/sst","slug":"in-name-router-the-route-path-path-must","errorCode":null,"errorMessage":"In \"${name}\" Router, the route path \"${path}\" must start with a \"/\"","messagePattern":"In \"(.+?)\" Router, the route path \"(.+?)\" must start with a \"/\"","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/src/components/aws/router.ts","lineNumber":1747,"sourceCode":"        return protection;\n      });\n    }\n\n    function handleInlineRoutes() {\n      let defaultCachePolicy: cloudfront.CachePolicy;\n      let defaultCfFunction: cloudfront.Function;\n      let defaultOac: OriginAccessControl;\n      const routes = normalizeRoutes();\n      const cdn = createCdn();\n      return cdn;\n\n      function normalizeRoutes() {\n        return output(args.routes!).apply((routes) => {\n          const normalizedRoutes = Object.fromEntries(\n            Object.entries(routes).map(([path, route]) => {\n              // Route path must start with \"/\"\n              if (!path.startsWith(\"/\"))\n                throw new Error(\n                  `In \"${name}\" Router, the route path \"${path}\" must start with a \"/\"`,\n                );\n\n              route = typeof route === \"string\" ? { url: route } : route;\n\n              const hasUrl = \"url\" in route ? 1 : 0;\n              const hasBucket = \"bucket\" in route ? 1 : 0;\n              if (hasUrl + hasBucket !== 1)\n                throw new Error(\n                  `In \"${name}\" Router, the route path \"${path}\" can only have one of url or bucket`,\n                );\n\n              return [path, route];\n            }),\n          );\n\n          normalizedRoutes[\"/*\"] = normalizedRoutes[\"/*\"] ?? {\n            url: \"https://do-not-exist.sst.dev\",","sourceCodeStart":1729,"sourceCodeEnd":1765,"githubUrl":"https://github.com/anomalyco/sst/blob/a0bd20f762883e72a35caccb4896c42ce5b3f707/platform/src/components/aws/router.ts#L1729-L1765","documentation":"Router inline route keys are CloudFront cache-behavior path patterns and must be absolute paths beginning with \"/\". normalizeRoutes validates each key and throws if a path does not start with a slash.","triggerScenarios":"`new Router(..., { routes: { \"*\": ..., \"api/*\": ... } })` — any route key missing the leading \"/\".","commonSituations":"Copy-pasting express-style route patterns (\"*\", \"api/*\", \"home\") into the Router routes map.","solutions":["Prefix every route key with \"/\" (e.g. \"*\" -> \"/*\", \"api/*\" -> \"/api/*\")","Validate route keys come from a map you control rather than user/external input"],"exampleFix":"// before\nroutes: { \"*\": \"https://example.com\" }\n// after\nroutes: { \"/*\": \"https://example.com\" }","handlingStrategy":"validation","validationCode":"const routes = { \"*\": \"https://example.com\" };\nfor (const path of Object.keys(routes)) {\n  if (!path.startsWith(\"/\"))\n    throw new Error(`Route path \"${path}\" must start with \"/\"`);\n}","typeGuard":"function isValidRoutePath(p: string): p is `/${string}` {\n  return p.startsWith(\"/\");\n}","tryCatchPattern":"try {\n  const r = new Router(ctx, \"R\", { routes });\n} catch (e) {\n  if (String(e).includes('must start with a \"/\"')) console.error(\"Fix route keys\");\n  throw e;\n}","preventionTips":["Normalize route keys with a helper that prefixes \"/\" before passing them to Router","Type route maps as Record<`/${string}`, ...> to catch it at compile time","Don't reuse express/glob patterns verbatim in Router configs"],"tags":["router","route-validation","path-format","sst"],"backgroundTag":"invalid-route-path","analyzedSha":"a0bd20f762883e72a35caccb4896c42ce5b3f707","analyzedAt":"2026-08-30T11:26:00.383Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}