{"record":{"id":"3f4a837bcc2d61f6","repo":"sveltejs/svelte","slug":"template-must-be-a-string","errorCode":null,"errorMessage":"Template must be a string","messagePattern":"Template must be a string","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/svelte/src/compiler/phases/1-parse/index.js","lineNumber":95,"sourceCode":"\t/** @type {AST.Fragment[]} */\n\tfragments = [];\n\n\t/** @type {AST.Root} */\n\troot;\n\n\t/** @type {Record<string, boolean>} */\n\tmeta_tags = {};\n\n\t/** @type {LastAutoClosedTag | undefined} */\n\tlast_auto_closed_tag;\n\n\t/**\n\t * @param {string} template\n\t * @param {boolean} loose\n\t */\n\tconstructor(template, loose) {\n\t\tif (typeof template !== 'string') {\n\t\t\tthrow new TypeError('Template must be a string');\n\t\t}\n\n\t\tthis.loose = loose;\n\t\tthis.template = template.trimEnd();\n\n\t\tlet match_lang;\n\n\t\tdo match_lang = regex_lang_attribute.exec(template);\n\t\twhile (match_lang && match_lang[0][1] !== 's'); // ensure it starts with '<s' to match script tags\n\n\t\tregex_lang_attribute.lastIndex = 0; // reset matched index to pass tests - otherwise declare the regex inside the constructor\n\n\t\tthis.ts = match_lang?.[2] === 'ts';\n\n\t\tthis.root = {\n\t\t\tcss: null,\n\t\t\tjs: [],\n\t\t\t// @ts-ignore","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/sveltejs/svelte/blob/20b341f10048cf1016a2028ac7eee5595cfef6a5/packages/svelte/src/compiler/phases/1-parse/index.js#L77-L113","documentation":"The parser's `Template` constructor requires the component source to be a string and throws a `TypeError` otherwise. This is a hard precondition guard at the entry of phase-1 parsing; the parser does not attempt coercion or defaulting. It is the first check before `template.trimEnd()` and language detection.","triggerScenarios":"Calling `parse()` (or any compile entry point that constructs `Template`) with a non-string argument: `undefined`, `null`, a Buffer/Uint8Array, a number, or an already-parsed AST object. The `typeof template !== 'string'` branch fires.","commonSituations":"Tooling that reads a `.svelte` file as a Node `Buffer` and forgets to call `.toString()`; preprocessors returning the wrong shape; programmatic callers that pass `null` when a file is missing; or test fixtures loading files with `fs.readFileSync` without an encoding argument.","solutions":["Ensure the source passed to `parse`/`compile`/`preprocess` is a string — call `.toString('utf8')` on Buffers and `.toString()` on string-like values.","Add a typeof check before calling compile and surface a clearer upstream error.","When using `fs.readFileSync`, pass `'utf8'` as the encoding so the result is already a string."],"exampleFix":"// before\nimport { readFileSync } from 'node:fs';\nimport { compile } from 'svelte/compiler';\nconst result = compile(readFileSync('./Comp.svelte')); // Buffer, not string\n\n// after\nconst result = compile(readFileSync('./Comp.svelte', 'utf8'));","handlingStrategy":"type-guard","validationCode":"// Validate before parsing.\nimport { compile } from 'svelte/compiler';\nfunction safeCompile(filename, source) {\n  if (typeof source !== 'string') {\n    throw new TypeError(`${filename}: expected string source, got ${typeof source}`);\n  }\n  return compile(source, { filename });\n}","typeGuard":"/** @param {unknown} s */\nfunction isTemplateSource(s) {\n  return typeof s === 'string';\n}\n\nif (!isTemplateSource(maybeSource)) {\n  throw new TypeError('Template source must be a string');\n}\nparse(maybeSource);","tryCatchPattern":null,"preventionTips":["Always pass an encoding to `fs.readFileSync(path, 'utf8')` so the result is a string.","Add a typeof guard at the boundary of any tool that feeds the compiler.","Normalize inputs in preprocessors — never forward Buffers or null to `compile`/`parse`."],"tags":["compiler","parser","typeerror","input-validation","node"],"backgroundTag":null,"analyzedSha":"20b341f10048cf1016a2028ac7eee5595cfef6a5","analyzedAt":"2026-08-12T23:37:30.399Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}