sveltejs/kit · error · Error
The following _redirects rule cannot be excluded by _routes.
Error message
The following _redirects rule cannot be excluded by _routes.json: ${line} What it means
The adapter parses a `_redirects` file to mirror its rules into `_routes.json` excludes so redirect paths skip the Worker. Path patterns containing placeholders (`/:param`-style or splat expressions) cannot be represented as exact excludes, so the adapter throws rather than generating an incorrect _routes.json that would break the redirects.
Source
Thrown at packages/adapter-cloudflare/utils.js:73
/**
* Extracts the redirect source from each line of a [_redirects](https://developers.cloudflare.com/pages/configuration/redirects/)
* file so we can exclude them in [_routes.json](https://developers.cloudflare.com/pages/functions/routing/#create-a-_routesjson-file)
* to ensure the redirect is invoked instead of the Cloudflare Worker.
* @param {string} file_contents
* @returns {string[]}
*/
export function parse_redirects(file_contents) {
/** @type {string[]} */
const redirects = [];
for (const line of file_contents.split('\n')) {
const content = line.trim();
if (!content || content.startsWith('#')) continue;
const [pathname] = line.split(' ');
// pathnames with placeholders are not supported
if (!pathname || pathname.includes('/:')) {
throw new Error(`The following _redirects rule cannot be excluded by _routes.json: ${line}`);
}
redirects.push(pathname);
}
return redirects;
}
/**
* Generates the [_routes.json](https://developers.cloudflare.com/pages/functions/routing/#create-a-_routesjson-file)
* file that dictates which routes invoke the Cloudflare Worker.
* @param {import('@sveltejs/kit').Builder} builder
* @param {string[]} client_assets
* @param {string[]} redirects
* @param {import('./index.js').AdapterOptions['routes']} routes
* @returns {import('./index.js').RoutesJSONSpec}
*/
export function get_routes_json(builder, client_assets, redirects, routes) {
const include = routes?.include ?? ['/*'];View on GitHub (pinned to 03f1687fe6)
Solutions
- Replace placeholder-based rules with explicit literal paths, e.g. `/blog/post-1 /new-url` per path.
- Move dynamic redirect logic into a SvelteKit endpoint or a Cloudflare Worker rule instead of _redirects.
- Delete or comment out (prefix with #) the unsupported placeholder lines if they are not needed.
- Check for formatting issues: split on single spaces so the pathname is a clean literal path.
Example fix
// before (_redirects) /blog/:slug /posts/:slug 301 // after (_redirects) /blog/hello /posts/hello 301 /blog/world /posts/world 301
Defensive patterns
Strategy: validation
Validate before calling
for (const line of redirectsFile.split('\n')) {
const content = line.trim();
if (!content || content.startsWith('#')) continue;
const [pathname] = line.split(' ');
if (!pathname || pathname.includes('/:')) {
throw new Error(`Unsupported _redirects rule: ${line}`);
}
} Type guard
function isPlainRedirectPath(pathname) {
return typeof pathname === 'string' && pathname.length > 0 && !pathname.includes('/:');
} Try / catch
try {
await viteBuild();
} catch (e) {
if (String(e).includes('_redirects rule cannot be excluded')) {
console.error('Replace placeholder-based _redirects rules with literal paths or Worker logic');
process.exit(1);
}
throw e;
} Prevention
- Keep only literal-path rules in _redirects; no :param or splat placeholders.
- Implement dynamic redirects in SvelteKit +server.js endpoints instead.
- When migrating from Netlify, rewrite placeholder rules explicitly.
- Lint _redirects for placeholder patterns (`/:`) in CI before building.
When it happens
Trigger: A `_redirects` file (in the project or static dir) contains a line whose pathname is empty or contains `/:` (placeholder segments), parsed during adapt or by the redirects option.
Common situations: Migrating a Netlify `_redirects` file that uses dynamic path segments like `/blog/:slug`; copying Cloudflare Pages redirect examples with placeholders; malformed lines with extra spaces producing an empty pathname.
Related errors
- routes.include and routes.exclude must be arrays
- routes.include must contain at least one route
- You must remove all `site` keys in ${config_path}. Consult h
- You must specify the `assets.directory` key in ${config_path
- You must specify the `assets.binding` key in ${config_path}
AI-assisted analysis of sveltejs/kit@03f1687fe6 (2026-09-02).
Data as JSON: /api/errors/b4a77c50970c9c71.
Report an issue: GitHub.