{"record":{"id":"f0955917df48b2bc","repo":"sveltejs/kit","slug":"keypath-must-be-an-array-of-strings","errorCode":null,"errorMessage":"${keypath} must be an array of strings","messagePattern":"(.+?) must be an array of strings","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/kit/src/core/config/options.js","lineNumber":127,"sourceCode":"\t\t{\n\t\t\ttracing: removed(\n\t\t\t\t(keypath) =>\n\t\t\t\t\t`\\`${keypath}\\` has been removed. Server-side tracing is now configured via \\`tracing.server\\``\n\t\t\t),\n\t\t\tinstrumentation: removed(\n\t\t\t\t(keypath) =>\n\t\t\t\t\t`\\`${keypath}\\` has been removed. \\`src/instrumentation.server.js\\` is now included in the build automatically when it exists; no opt-in is required`\n\t\t\t),\n\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'),","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/sveltejs/kit/blob/03f1687fe612ce3d2d9131139b5b188d9cf90c64/packages/kit/src/core/config/options.js#L109-L145","documentation":"The `extensions` config option controls which file extensions SvelteKit treats as routable pages. It must be an array whose every member is a string. SvelteKit throws this when the value is not an array or contains non-string entries.","triggerScenarios":"Setting `extensions` to a string (e.g. `extensions: '.svelte'`), to a non-array value, or to an array containing numbers/objects/null (e.g. `extensions: ['.svelte', null]`).","commonSituations":"Hand-editing svelte.config.js and forgetting array brackets; generating config from JSON where an env list is comma-joined into a single string; typos like `extensions: ['.svelte', 1]`.","solutions":["Wrap the value in an array: `extensions: ['.svelte']`","Ensure every member is a string — remove non-string entries","If building from an env var, split it: `process.env.EXTENSIONS?.split(',') ?? ['.svelte']`"],"exampleFix":"// before\nconst config = { extensions: '.svelte,.js' };\n// after\nconst config = { extensions: ['.svelte', '.js'] };","handlingStrategy":"type-guard","validationCode":"if (!Array.isArray(config.extensions) || !config.extensions.every((e) => typeof e === 'string')) {\n  throw new Error('extensions must be an array of strings');\n}","typeGuard":"function isStringArray(v) {\n  return Array.isArray(v) && v.every((e) => typeof e === 'string');\n}","tryCatchPattern":"try {\n  build({ config });\n} catch (e) {\n  if (String(e.message).includes('must be an array of strings')) {\n    console.error('Wrap extensions in an array of strings');\n  }\n  throw e;\n}","preventionTips":["Always write extension lists as arrays with quoted string members","When deriving from env vars, split strings into arrays explicitly","Add a config sanity check script in CI before building"],"tags":["config","type-error","validation"],"backgroundTag":"invalid-config-value","analyzedSha":"03f1687fe612ce3d2d9131139b5b188d9cf90c64","analyzedAt":"2026-09-02T02:01:50.504Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}