{"record":{"id":"5929afa74155a2a8","repo":"sveltejs/kit","slug":"routes-include-must-contain-at-least-one-route","errorCode":null,"errorMessage":"routes.include must contain at least one route","messagePattern":"routes\\.include must contain at least one route","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/adapter-cloudflare/utils.js","lineNumber":99,"sourceCode":"/**\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 ?? ['/*'];\n\tlet exclude = routes?.exclude ?? ['<all>'];\n\n\tif (!Array.isArray(include) || !Array.isArray(exclude)) {\n\t\tthrow new Error('routes.include and routes.exclude must be arrays');\n\t}\n\n\tif (include?.length === 0) {\n\t\tthrow new Error('routes.include must contain at least one route');\n\t}\n\n\tif (include?.length > 100) {\n\t\tthrow new Error('routes.include must contain 100 or fewer routes');\n\t}\n\n\t/** @type {Set<string>} */\n\tconst transformed_rules = new Set();\n\tfor (const rule of exclude) {\n\t\tif (rule === '<all>') {\n\t\t\ttransformed_rules.add('<build>');\n\t\t\ttransformed_rules.add('<files>');\n\t\t\ttransformed_rules.add('<prerendered>');\n\t\t\ttransformed_rules.add('<redirects>');\n\t\t} else {\n\t\t\ttransformed_rules.add(rule);\n\t\t}\n\t}","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/sveltejs/kit/blob/03f1687fe612ce3d2d9131139b5b188d9cf90c64/packages/adapter-cloudflare/utils.js#L81-L117","documentation":"Cloudflare limits the number of route include patterns in `_routes.json` (100 include rules for Workers with static assets). The adapter validates this at build time so deployment doesn't fail later at Cloudflare with an opaque error.","triggerScenarios":"Providing an adapter `routes.include` array with more than 100 entries during adapt/get_routes_json (e.g. enumerating hundreds of individual paths).","commonSituations":"Excluding many API endpoints by listing each path individually instead of using wildcards; auto-generated route lists from a CMS with many top-level paths.","solutions":["Consolidate patterns with wildcards, e.g. ['/api/*'] instead of listing every endpoint.","Invert the logic: use exclude patterns for the minority of paths instead of enumerating includes.","Trim the include list to under 100 entries, prioritizing the highest-traffic routes.","If genuinely more than 100 distinct patterns are needed, reconsider using _routes.json and handle routing inside the Worker."],"exampleFix":"// before\nroutes: { include: ['/a', '/b', '/c', /* ...150 paths */] }\n\n// after\nroutes: { include: ['/api/*'], exclude: ['/static/*', '/favicon.ico'] }","handlingStrategy":"validation","validationCode":"const include = routes?.include ?? ['/*'];\nif (include.length > 100) {\n  throw new Error('routes.include must contain 100 or fewer routes');\n}","typeGuard":"function withinRouteLimit(include) {\n  return Array.isArray(include) && include.length <= 100;\n}","tryCatchPattern":"try {\n  await viteBuild();\n} catch (e) {\n  if (String(e).includes('100 or fewer routes')) {\n    console.error('Consolidate routes.include patterns with wildcards');\n    process.exit(1);\n  }\n  throw e;\n}","preventionTips":["Prefer wildcard patterns like ['/api/*'] over enumerating paths.","Count routes.include entries in CI before building.","Use exclude patterns for minority-path exclusion instead of many includes.","Revisit routing strategy if you legitimately need more than 100 patterns."],"tags":["cloudflare","routes-json","adapter-config","limits"],"backgroundTag":"route-limit-exceeded","analyzedSha":"03f1687fe612ce3d2d9131139b5b188d9cf90c64","analyzedAt":"2026-09-02T02:01:50.504Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}