{"record":{"id":"25580a1a44fe42a8","repo":"sveltejs/kit","slug":"file-extensions-must-be-alphanumeric-saw-exte","errorCode":null,"errorMessage":"File extensions must be alphanumeric — saw '${extension}'","messagePattern":"File extensions must be alphanumeric — saw '(.+?)'","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/kit/src/core/config/options.js","lineNumber":136,"sourceCode":"\t\t\tremoteFunctions: boolean(false),\n\t\t\tforkPreloads: boolean(false),\n\t\t\thandleRenderingErrors: removed()\n\t\t},\n\t\ttrue\n\t),\n\n\textensions: validate(['.svelte'], (input, keypath) => {\n\t\tif (!Array.isArray(input) || !input.every((page) => typeof page === 'string')) {\n\t\t\tthrow new Error(`${keypath} must be an array of strings`);\n\t\t}\n\n\t\tinput.forEach((extension) => {\n\t\t\tif (extension[0] !== '.') {\n\t\t\t\tthrow new Error(`Each member of ${keypath} must start with '.' — saw '${extension}'`);\n\t\t\t}\n\n\t\t\tif (!/^(\\.[a-z0-9]+)+$/i.test(extension)) {\n\t\t\t\tthrow new Error(`File extensions must be alphanumeric — saw '${extension}'`);\n\t\t\t}\n\t\t});\n\n\t\treturn input;\n\t}),\n\n\tfiles: object({\n\t\tsrc: string('src'),\n\t\tassets: string('static'),\n\t\thooks: object({\n\t\t\tclient: string(null),\n\t\t\tserver: string(null),\n\t\t\tuniversal: string(null)\n\t\t}),\n\t\tlib: removed(\n\t\t\t(keypath) =>\n\t\t\t\t`\\`${keypath}\\` has been removed. Use #lib instead of $lib: https://svelte.dev/docs/kit/$lib`\n\t\t),","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/sveltejs/kit/blob/03f1687fe612ce3d2d9131139b5b188d9cf90c64/packages/kit/src/core/config/options.js#L118-L154","documentation":"After checking for a leading dot, SvelteKit requires each `extensions` entry to match `/^(\\.[a-z0-9]+)+$/i` — i.e. only dot-separated alphanumeric segments (`.svelte`, `.md.svelte` is fine; `.svelte-kit-files` with dashes is not). This keeps extensions usable as filename suffixes.","triggerScenarios":"Entries like `.s-v-e-l-t-e`, `.md!`, `.js;` or any extension containing non-alphanumeric characters after the dot.","commonSituations":"Trying to register multi-part or unusual suffixes with hyphens/underscores; copying glob fragments like `*.page.svelte` into the extensions list.","solutions":["Use only alphanumeric characters after dots: `.svelte`, `.js`, `.svx`","Remove special characters or split into separate dot-delimited alphanumeric segments","If the desired filename pattern cannot be an extension, handle routing differently (e.g. rename files) instead of extending `extensions`"],"exampleFix":"// before\nexport default { extensions: ['.svelte', '.my-page'] };\n// after\nexport default { extensions: ['.svelte', '.mypage'] };","handlingStrategy":"validation","validationCode":"const re = /^(\\.[a-z0-9]+)+$/i;\nfor (const ext of config.extensions ?? []) {\n  if (!re.test(ext)) {\n    throw new Error(`Extension '${ext}' must be dot-separated alphanumeric`);\n  }\n}","typeGuard":"function isAlphanumericExtension(v) {\n  return Array.isArray(v) && v.every((e) => typeof e === 'string' && /^(\\.[a-z0-9]+)+$/i.test(e));\n}","tryCatchPattern":"try {\n  checkExtensions(config.extensions);\n} catch (e) {\n  if (String(e.message).includes('must be alphanumeric')) {\n    console.error('Remove special characters from extensions');\n  }\n  throw e;\n}","preventionTips":["Stick to standard extensions like `.svelte`, `.js`, `.svx`, `.md`","Test any new extension against `/^(\\.[a-z0-9]+)+$/i` before adding it","Avoid hyphens, underscores and glob syntax in extension names"],"tags":["config","validation","regex"],"backgroundTag":"invalid-config-value","analyzedSha":"03f1687fe612ce3d2d9131139b5b188d9cf90c64","analyzedAt":"2026-09-02T02:01:50.504Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}