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

  1. Replace placeholder-based rules with explicit literal paths, e.g. `/blog/post-1 /new-url` per path.
  2. Move dynamic redirect logic into a SvelteKit endpoint or a Cloudflare Worker rule instead of _redirects.
  3. Delete or comment out (prefix with #) the unsupported placeholder lines if they are not needed.
  4. 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

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


AI-assisted analysis of sveltejs/kit@03f1687fe6 (2026-09-02). Data as JSON: /api/errors/b4a77c50970c9c71. Report an issue: GitHub.