vercel/next.js · error
Each route must start with '/': ${route}
Error message
Each route must start with '/': ${route} What it means
Thrown by parseRoutes (benchmark.ts:141) when a route in the --routes list does not start with '/'. The benchmark builds URLs as http://127.0.0.1:{port}{route}, so a route without a leading slash would either be a relative URL (resolving against the base incorrectly) or produce a malformed path. The check enforces the absolute-path convention before any request is made.
Source
Thrown at bench/render-pipeline/benchmark.ts:141
'/streaming/heavy',
'/streaming/chunkstorm',
'/streaming/wide',
'/streaming/bulk',
]
}
const routes = rawRoutes
.split(',')
.map((route) => route.trim())
.filter(Boolean)
if (routes.length === 0) {
throw new Error('--routes cannot be empty')
}
for (const route of routes) {
if (!route.startsWith('/')) {
throw new Error(`Each route must start with '/': ${route}`)
}
}
return routes
}
function usage() {
console.log(`Usage: pnpm bench:render-pipeline [options]
Options:
--scenario=e2e|minimal-server (default: e2e)
e2e: Real production server (next build + next start).
minimal-server: NextServer with minimalMode, no router-server.
--json-out=<path>
Benchmark options:
--app-dir=<path> (default: bench/basic-app)
--routes=/,/streaming/light,... (default: built-in stress suite)View on GitHub (pinned to 0ae8c72462)
Solutions
- Prefix every route with '/', e.g. --routes=/dashboard,/streaming/light.
- If you meant to benchmark the root, use '/' (not empty string).
- Do not include scheme/host; pass only the path portion.
- Re-check after comma-splitting that no entry lost its slash.
Example fix
# before # pnpm bench:render-pipeline --routes=dashboard,/blog # after # pnpm bench:render-pipeline --routes=/dashboard,/blog
Defensive patterns
Strategy: validation
Validate before calling
function normalizeRoute(route: string): string {
const trimmed = route.trim()
if (!trimmed.startsWith('/')) throw new Error(`route must start with '/': ${route}`)
return trimmed
}
// apply to every entry before passing to parseRoutes Type guard
function isAbsolutePathRoute(route: string): boolean {
return route.startsWith('/')
} Try / catch
try {
const routes = parseRoutes(args.get('routes'))
} catch (err) {
if (/must start with '\/' .test((err as Error).message)) {
console.error('Each route must be an absolute path (start with /). Got:', (err as Error).message)
process.exit(2)
}
throw err
} Prevention
- Prefix every route with '/'; the root is '/', not empty.
- Pass only the path portion, never scheme/host.
- Double-check entries after comma-splitting.
- If sourcing routes from a config, normalize them at the source.
When it happens
Trigger: Passing --routes=dashboard (missing slash), --routes=/streaming/light,dashboard (one bad entry), or routes with a hostname like http://host/x. Each entry is checked individually so one bad route aborts the whole list.
Common situations: Typing routes without the leading slash; pasting route names from a config that omits the slash; mixing in a full URL where a path was expected.
Related errors
- --routes cannot be empty
- Invalid numeric value for --${key}: ${value}
- Invalid --scenario value: ${scenarioRaw}. Use e2e|minimal-se
- Invalid --stream-mode value: ${streamModeRaw}. Use node
- Invalid --top value: ${topRaw}
AI-assisted analysis of vercel/next.js@0ae8c72462 (2026-08-06).
Data as JSON: /api/errors/66b4647ef728ae88.
Report an issue: GitHub.