anomalyco/sst · error
Invalid route type
Error message
Invalid route type
What it means
Inside createCdn, route entries are normalized into CloudFront origin definitions per route type. After normalization any route not matching a known type (url or bucket) reaches the terminal `throw new Error("Invalid route type")`, indicating the internal route union was exhausted without a match.
Source
Thrown at platform/src/components/aws/router.ts:2027
path,
route.edge.viewerResponse,
).arn,
},
]
: []),
],
viewerProtocolPolicy: "redirect-to-https",
allowedMethods: ["GET", "HEAD", "OPTIONS"],
cachedMethods: ["GET", "HEAD"],
compress: true,
// CloudFront's managed CachingOptimized policy
cachePolicyId:
route.cachePolicy ??
"658327ea-f89d-4fab-a63d-7e88639e58f6",
},
};
}
throw new Error("Invalid route type");
},
);
return new Cdn(
...transform(
args.transform?.cdn,
`${name}Cdn`,
{
comment: `${name} router`,
origins: distributionData.map((d) => d.origin),
defaultCacheBehavior: {
...distributionData.find(
(d) => d.behavior.pathPattern === "/*",
)!.behavior,
// @ts-expect-error
pathPattern: undefined,
},
orderedCacheBehaviors: distributionDataView on GitHub (pinned to a0bd20f762)
Solutions
- Ensure each route is either a plain URL string or an object with only `url` (+ optional url args) or `bucket` (+ optional bucket args)
- Log/inspect the routes config you pass to Router to find the malformed entry
- Upgrade SST — if it occurs with seemingly valid config, it may be a version bug; check the Router docs for the current route shape
Example fix
// before
routes: { "/*": { href: "https://example.com" } } // unknown key
// after
routes: { "/*": { url: "https://example.com" } } Defensive patterns
Strategy: type-guard
Validate before calling
const known = (r: any) =>
typeof r === "string" ||
(r && ("url" in r || "bucket" in r)) &&
Object.keys(r).every((k) => ["url", "bucket"].includes(k));
Object.values(routes).forEach((r) => { if (!known(r)) throw new Error("Unknown route shape: " + JSON.stringify(r)); }); Type guard
function isKnownRoute(r: unknown): r is string | { url: unknown } | { bucket: unknown } {
return typeof r === "string" ||
(typeof r === "object" && r !== null && ("url" in r || "bucket" in r));
} Try / catch
try {
const r = new Router(ctx, "R", { routes });
} catch (e) {
if (String(e) === "Invalid route type") console.error("Malformed route entry passed to Router");
throw e;
} Prevention
- Only pass route shapes from the documented Router API (string, {url}, {bucket})
- Never cast arbitrary JSON as route args
- After SST upgrades, rebuild route configs against the current docs
When it happens
Trigger: A route object in `args.routes` whose normalized shape matches neither the url-route nor bucket-route variant when building the CDN origins — typically from a non-standard route object shape passed through the routes map.
Common situations: Manually crafted route objects with malformed/unexpected fields; internal drift between route normalization and CDN creation when upgrading SST; casting arbitrary objects as routes.
Related errors
- There have been some minor changes to the "Router" component
- In "${name}" Router, the route path "${path}" must start wit
- In "${name}" Router, the route path "${path}" can only have
- Cannot set "protection" on a Router with inline routes. Use
- Cannot use both `routes` and `.route()` function to add rout
AI-assisted analysis of anomalyco/sst@a0bd20f762 (2026-08-30).
Data as JSON: /api/errors/2bcb6eb436f7269f.
Report an issue: GitHub.