{"record":{"id":"37d99819d2899b05","repo":"sveltejs/kit","slug":"cannot-save-decoded-as-it-is-already-a-director","errorCode":null,"errorMessage":"Cannot save ${decoded} as it is already a directory. See https://svelte.dev/docs/kit/page-options#prerender-route-conflicts for more information","messagePattern":"Cannot save (.+?) as it is already a directory\\. See https://svelte\\.dev/docs/kit/page-options#prerender-route-conflicts for more information","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/kit/src/core/postbuild/prerender.js","lineNumber":594,"sourceCode":"\t\t\t\t\tif (!prerendered.redirects.has(decoded)) {\n\t\t\t\t\t\tprerendered.redirects.set(decoded, {\n\t\t\t\t\t\t\tstatus: response.status,\n\t\t\t\t\t\t\tlocation: resolved\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tprerendered.paths.push(decoded);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tlog.warn(`location header missing on redirect received from ${decoded}`);\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tif (response.status === 200) {\n\t\t\tif (existsSync(dest) && statSync(dest).isDirectory()) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Cannot save ${decoded} as it is already a directory. See https://svelte.dev/docs/kit/page-options#prerender-route-conflicts for more information`\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst dir = dirname(dest);\n\n\t\t\tif (existsSync(dir) && !statSync(dir).isDirectory()) {\n\t\t\t\tconst parent = decoded.split('/').slice(0, -1).join('/');\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Cannot save ${decoded} as ${parent} is already a file. See https://svelte.dev/docs/kit/page-options#prerender-route-conflicts for more information`\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tmkdirSync(dir, { recursive: true });\n\n\t\t\twriteFileSync(dest, body);\n\t\t\twritten.add(file);\n","sourceCodeStart":576,"sourceCodeEnd":612,"githubUrl":"https://github.com/sveltejs/kit/blob/03f1687fe612ce3d2d9131139b5b188d9cf90c64/packages/kit/src/core/postbuild/prerender.js#L576-L612","documentation":"Two prerendered routes resolved to the same output path, where one route already wrote a directory at that path (e.g. a route `/foo` produced directory `foo/` containing `foo/index.html`) and now another route wants to save a file at exactly that path. The prerenderer aborts rather than clobber the directory.","triggerScenarios":"Having routes like `/foo` (page) and a second route whose normalized path is also `foo` after trailing-slash/trailing-encoding normalization (e.g. route `foo` with different trailing slash config) so save() computes the same `dest` for a file while a directory exists.","commonSituations":"Mixing trailingSlash settings between two overlapping routes; a dynamic route `[slug]` and a static route colliding after prerender normalization; duplicate endpoints that both return 200 for the same URL.","solutions":["Find the two conflicting routes from the error message and rename or remove one","Align trailingSlash export on both routes so they resolve to distinct output paths","Ensure dynamic route params don't generate the same URL as an existing static route","Consult https://svelte.dev/docs/kit/page-options#prerender-route-conflicts for resolution patterns"],"exampleFix":"// before — both /foo and /foo/ rendered (default trailingSlash)\n// src/routes/foo/+page.js: export const trailingSlash = 'always';\n// src/routes/foo/bar conflicting...\n\n// after — pick one convention\n// src/routes/foo/+page.js: export const trailingSlash = 'never'; // and remove the duplicate route","handlingStrategy":"validation","validationCode":"// audit route dirs for overlapping normalized paths before build\nconst paths = ['src/routes/foo/+page.svelte', 'src/routes/foo/'];\nconst normalized = new Set();\nfor (const p of paths) {\n  const key = p.replace(/^src\\/routes/, '').replace(/\\/+$/, '');\n  if (normalized.has(key)) console.warn('Prerender conflict at', key);\n  normalized.add(key);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await prerender();\n} catch (e) {\n  if (String(e.message).includes('already a directory')) {\n    console.error('Two routes write to the same path; rename one route');\n  }\n  throw e;\n}","preventionTips":["Standardize one trailingSlash setting app-wide","Ensure dynamic params cannot equal existing static route paths","Grep routes for duplicate path segments before large refactors"],"tags":["prerender","route-conflict","filesystem"],"backgroundTag":"prerender-route-conflict","analyzedSha":"03f1687fe612ce3d2d9131139b5b188d9cf90c64","analyzedAt":"2026-09-02T02:01:50.504Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}