{"record":{"id":"b4a77c50970c9c71","repo":"sveltejs/kit","slug":"the-following-redirects-rule-cannot-be-excluded-b","errorCode":null,"errorMessage":"The following _redirects rule cannot be excluded by _routes.json: ${line}","messagePattern":"The following _redirects rule cannot be excluded by _routes\\.json: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/adapter-cloudflare/utils.js","lineNumber":73,"sourceCode":"/**\n * Extracts the redirect source from each line of a [_redirects](https://developers.cloudflare.com/pages/configuration/redirects/)\n * file so we can exclude them in [_routes.json](https://developers.cloudflare.com/pages/functions/routing/#create-a-_routesjson-file)\n * to ensure the redirect is invoked instead of the Cloudflare Worker.\n * @param {string} file_contents\n * @returns {string[]}\n */\nexport function parse_redirects(file_contents) {\n\t/** @type {string[]} */\n\tconst redirects = [];\n\n\tfor (const line of file_contents.split('\\n')) {\n\t\tconst content = line.trim();\n\t\tif (!content || content.startsWith('#')) continue;\n\n\t\tconst [pathname] = line.split(' ');\n\t\t// pathnames with placeholders are not supported\n\t\tif (!pathname || pathname.includes('/:')) {\n\t\t\tthrow new Error(`The following _redirects rule cannot be excluded by _routes.json: ${line}`);\n\t\t}\n\t\tredirects.push(pathname);\n\t}\n\n\treturn redirects;\n}\n\n/**\n * Generates the [_routes.json](https://developers.cloudflare.com/pages/functions/routing/#create-a-_routesjson-file)\n * file that dictates which routes invoke the Cloudflare Worker.\n * @param {import('@sveltejs/kit').Builder} builder\n * @param {string[]} client_assets\n * @param {string[]} redirects\n * @param {import('./index.js').AdapterOptions['routes']} routes\n * @returns {import('./index.js').RoutesJSONSpec}\n */\nexport function get_routes_json(builder, client_assets, redirects, routes) {\n\tconst include = routes?.include ?? ['/*'];","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/sveltejs/kit/blob/03f1687fe612ce3d2d9131139b5b188d9cf90c64/packages/adapter-cloudflare/utils.js#L55-L91","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (_redirects)\n/blog/:slug /posts/:slug 301\n\n// after (_redirects)\n/blog/hello /posts/hello 301\n/blog/world /posts/world 301","handlingStrategy":"validation","validationCode":"for (const line of redirectsFile.split('\\n')) {\n  const content = line.trim();\n  if (!content || content.startsWith('#')) continue;\n  const [pathname] = line.split(' ');\n  if (!pathname || pathname.includes('/:')) {\n    throw new Error(`Unsupported _redirects rule: ${line}`);\n  }\n}","typeGuard":"function isPlainRedirectPath(pathname) {\n  return typeof pathname === 'string' && pathname.length > 0 && !pathname.includes('/:');\n}","tryCatchPattern":"try {\n  await viteBuild();\n} catch (e) {\n  if (String(e).includes('_redirects rule cannot be excluded')) {\n    console.error('Replace placeholder-based _redirects rules with literal paths or Worker logic');\n    process.exit(1);\n  }\n  throw e;\n}","preventionTips":["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."],"tags":["cloudflare","redirects","routes-json","adapter-config"],"backgroundTag":"unsupported-redirect-pattern","analyzedSha":"03f1687fe612ce3d2d9131139b5b188d9cf90c64","analyzedAt":"2026-09-02T02:01:50.504Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}