{"record":{"id":"18692f54f6f38a99","repo":"sveltejs/kit","slug":"keypath-option-must-not-end-with-see-https","errorCode":null,"errorMessage":"${keypath} option must not end with '/'. See https://svelte.dev/docs/kit/configuration#paths","messagePattern":"(.+?) option must not end with '/'\\. See https://svelte\\.dev/docs/kit/configuration#paths","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/kit/src/core/config/options.js","lineNumber":209,"sourceCode":"\t\t\t\tthrow new Error(\n\t\t\t\t\t`${keypath} option must either be the empty string or a root-relative path that starts but doesn't end with '/'. See https://svelte.dev/docs/kit/configuration#paths`\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn input;\n\t\t}),\n\t\tassets: validate('', (input, keypath) => {\n\t\t\tassert_string(input, keypath);\n\n\t\t\tif (input) {\n\t\t\t\tif (!/^[a-z]+:\\/\\//.test(input)) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`${keypath} option must be an absolute path, if specified. See https://svelte.dev/docs/kit/configuration#paths`\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (input.endsWith('/')) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`${keypath} option must not end with '/'. See https://svelte.dev/docs/kit/configuration#paths`\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn input;\n\t\t}),\n\t\torigin: validate(undefined, (input, keypath) => {\n\t\t\tassert_string(input, keypath);\n\n\t\t\tlet url;\n\n\t\t\ttry {\n\t\t\t\turl = new URL(input);\n\t\t\t} catch {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`${keypath} must be a valid origin (e.g. 'https://my-site.com'). '${input}' could not be parsed as a URL`\n\t\t\t\t);","sourceCodeStart":191,"sourceCodeEnd":227,"githubUrl":"https://github.com/sveltejs/kit/blob/03f1687fe612ce3d2d9131139b5b188d9cf90c64/packages/kit/src/core/config/options.js#L191-L227","documentation":"When `paths.assets` is set to an absolute URL it must not end with `/`. SvelteKit joins asset paths itself, and a trailing slash would produce double-slash URLs like `https://cdn.example.com//_app/...`.","triggerScenarios":"`paths.assets: 'https://cdn.example.com/'` — any absolute URL with a trailing slash.","commonSituations":"Copying the CDN base URL straight from a browser address bar; CDN dashboards showing origins with trailing slashes.","solutions":["Remove the trailing slash: `https://cdn.example.com`","Normalize at config load: `assets.replace(/\\/$/, '')`","Verify generated asset URLs in the built output no longer contain `//`"],"exampleFix":"// before\npaths: { assets: 'https://cdn.example.com/' }\n// after\npaths: { assets: 'https://cdn.example.com' }","handlingStrategy":"validation","validationCode":"const assets = config.paths?.assets;\nif (typeof assets === 'string' && assets.endsWith('/')) {\n  throw new Error('paths.assets must not end with \"/\"');\n}","typeGuard":"function hasNoTrailingSlash(v) {\n  return v === undefined || v === '' || (typeof v === 'string' && !v.endsWith('/'));\n}","tryCatchPattern":"try {\n  assertNoTrailingSlash(config.paths?.assets);\n} catch (e) {\n  if (String(e.message).includes(\"must not end with '/'\")) {\n    console.error('Strip the trailing slash from the CDN origin');\n  }\n  throw e;\n}","preventionTips":["Store CDN origins without trailing slashes in env/dashboards","Normalize once at config load: `assets.replace(/\\/$/, '')`","Inspect built HTML for `//` in asset URLs after changing CDN settings"],"tags":["config","paths","url"],"backgroundTag":"invalid-url-format","analyzedSha":"03f1687fe612ce3d2d9131139b5b188d9cf90c64","analyzedAt":"2026-09-02T02:01:50.504Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}