{"record":{"id":"07413057c231d1e3","repo":"sveltejs/kit","slug":"invalid-content-type-value-type-error-suff","errorCode":null,"errorMessage":"Invalid content-type value \"${type}\". ${error_suffix}","messagePattern":"Invalid content-type value \"(.+?)\"\\. (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/kit/src/runtime/server/validate-headers.js","lineNumber":45,"sourceCode":"\t\tconst parts = value.split(',').map((part) => part.trim());\n\t\tif (parts.some((part) => !part)) {\n\t\t\tthrow new Error(`\\`cache-control\\` header contains empty directives. ${error_suffix}`);\n\t\t}\n\n\t\tconst directives = parts.map((part) => part.split('=')[0].toLowerCase());\n\t\tconst invalid = directives.find((directive) => !VALID_CACHE_CONTROL_DIRECTIVES.has(directive));\n\t\tif (invalid) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invalid cache-control directive \"${invalid}\". Did you mean one of: ${[...VALID_CACHE_CONTROL_DIRECTIVES].join(', ')}? ${error_suffix}`\n\t\t\t);\n\t\t}\n\t},\n\n\t'content-type': (value) => {\n\t\tconst type = value.split(';')[0].trim();\n\t\tconst error_suffix = `(While parsing \"${value}\".)`;\n\t\tif (!CONTENT_TYPE_PATTERN.test(type)) {\n\t\t\tthrow new Error(`Invalid content-type value \"${type}\". ${error_suffix}`);\n\t\t}\n\t}\n};\n\n/**\n * @param {Record<string, string>} headers\n */\nexport function validateHeaders(headers) {\n\tfor (const [key, value] of Object.entries(headers)) {\n\t\tconst validator = HEADER_VALIDATORS[key.toLowerCase()];\n\t\ttry {\n\t\t\tvalidator?.(value);\n\t\t} catch (error) {\n\t\t\tif (error instanceof Error) {\n\t\t\t\tconsole.warn(`[SvelteKit] ${error.message}`);\n\t\t\t}\n\t\t}\n\t}","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/sveltejs/kit/blob/03f1687fe612ce3d2d9131139b5b188d9cf90c64/packages/kit/src/runtime/server/validate-headers.js#L27-L63","documentation":"The content-type value's media type (part before ';') must match a type/subtype pattern. Values like 'text' (missing subtype), 'invalid' bare tokens, or whitespace-mangled types throw with the parsed type and original value shown.","triggerScenarios":"setHeaders({ 'content-type': 'json' }) instead of 'application/json'; returning a Response whose headers include a malformed content-type like 'application/;' ; empty content-type string.","commonSituations":"Hand-rolled endpoint responses with abbreviated types; string concatenation that drops the subtype; copying only the MIME suffix ('xml', 'html') instead of the full type.","solutions":["Use the full media type: e.g. 'application/json', 'text/html; charset=utf-8'","Prefer Response.json() or the json() helper so the content-type is set correctly for you","Trim whitespace and ensure a '/' separates type and subtype"],"exampleFix":"// before\nevent.setHeaders({ 'content-type': 'json' });\n// after\nevent.setHeaders({ 'content-type': 'application/json' });","handlingStrategy":"validation","validationCode":"const CT = /^[*\\w.+/-]+\\/[\\w.+-]+$/;\nfunction isValidContentType(v) { return CT.test(v.split(';')[0].trim()); }\n// if (!isValidContentType('application/json')) throw ...","typeGuard":null,"tryCatchPattern":"try {\n  event.setHeaders({ 'content-type': type });\n} catch (e) {\n  if (e.message.startsWith('Invalid content-type')) console.error('Bad media type:', type);\n}","preventionTips":["Use full MIME types like application/json, never bare suffixes","Prefer Response.json()/json() helpers over manual content-type","Always include type/subtype separated by '/'"],"tags":["content-type","http-headers","validation"],"backgroundTag":"invalid-content-type-header","analyzedSha":"03f1687fe612ce3d2d9131139b5b188d9cf90c64","analyzedAt":"2026-09-02T02:01:50.504Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}