{"record":{"id":"610d7adffc00a047","repo":"withastro/astro","slug":"svg-file-does-not-contain-an-svg-element","errorCode":null,"errorMessage":"SVG file does not contain an <svg> element","messagePattern":"SVG file does not contain an <svg> element","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/astro/src/assets/svg/utils.ts","lineNumber":36,"sourceCode":"\tif (svgOptimizer) {\n\t\ttry {\n\t\t\tprocessedContents = await svgOptimizer.optimize(contents, path);\n\t\t} catch (cause) {\n\t\t\tthrow new AstroError(\n\t\t\t\t{\n\t\t\t\t\t...AstroErrorData.CannotOptimizeSvg,\n\t\t\t\t\tmessage: AstroErrorData.CannotOptimizeSvg.message(path, svgOptimizer.name),\n\t\t\t\t},\n\t\t\t\t{ cause },\n\t\t\t);\n\t\t}\n\t}\n\tconst root = parse(processedContents);\n\tconst svgNode = root.children.find(\n\t\t({ name, type }: { name: string; type: number }) => type === ELEMENT_NODE && name === 'svg',\n\t);\n\tif (!svgNode) {\n\t\tthrow new Error('SVG file does not contain an <svg> element');\n\t}\n\tconst { attributes, children } = svgNode;\n\tconst body = renderSync({ ...root, children });\n\n\t// Collect text content of <style> elements for head propagation and CSP hashing\n\tconst styles: string[] = [];\n\tfor (const child of children) {\n\t\tif (child.type === ELEMENT_NODE && child.name === 'style') {\n\t\t\tconst textContent = child.children\n\t\t\t\t?.filter((c: { type: number }) => c.type === TEXT_NODE)\n\t\t\t\t.map((c: { value: string }) => c.value)\n\t\t\t\t.join('');\n\t\t\tif (textContent) {\n\t\t\t\tstyles.push(textContent);\n\t\t\t}\n\t\t}\n\t}\n","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/withastro/astro/blob/157c500c38faa7ecf1251adbaeefcd109470d75c/packages/astro/src/assets/svg/utils.ts#L18-L54","documentation":"After optional optimization, Astro parses the SVG with ultrahtml and looks for a top-level `<svg>` element. If none is found it throws a plain Error ('SVG file does not contain an <svg> element') from packages/astro/src/assets/svg/utils.ts — the file parsed, but it is not actually an SVG document (no svg root element).","triggerScenarios":"An .svg file whose root is something else (an HTML page, a wrapper document, XML without an svg element); an empty or whitespace-only file with .svg extension; content that got mangled so the svg tag was stripped; an optimizer that returned non-SVG output.","commonSituations":"Saved a web page or received an XML error document and named it .svg; SVG generator emitted a wrapper with comments/doctype only; CI step that writes .svg files produced empty output; remote fetch saved an error body as .svg.","solutions":["Open the file in a text editor and confirm it literally contains an `<svg>...</svg>` root element","If it is an HTML or XML document, re-export the actual SVG from your design tool or source","If an optimizer step strips the root, remove it from the pipeline or fix its output, then retry"],"exampleFix":"```html\n<!-- before: hero.svg -->\n<html><body><p>Not found</p></body></html>\n\n<!-- after: hero.svg -->\n<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\">…</svg>\n```","handlingStrategy":"validation","validationCode":"// verify an SVG document actually contains a root <svg> element\nfunction hasSvgRoot(contents: string): boolean {\n  return /<svg[\\s>]/i.test(contents);\n}\n\nif (!hasSvgRoot(await readFile(path, 'utf8'))) {\n  throw new Error(`${path} is not a valid SVG document`);\n}","typeGuard":"function isSvgDocument(contents: string): boolean {\n  return /<svg[\\s>][\\s\\S]*<\\/svg>\\s*$/i.test(contents.trim());\n}","tryCatchPattern":"try {\n  await parseSvg({ path, contents });\n} catch (err) {\n  if (err instanceof Error && err.message.includes('does not contain an <svg> element')) {\n    // skip this file or fail the build with a clearer, path-aware message\n    throw new Error(`Invalid SVG asset: ${path}`);\n  }\n  throw err;\n}","preventionTips":["Generate .svg files only from real SVG exporters; never save web pages as .svg","Add a CI step that regex-checks every *.svg for an <svg> root"],"tags":["astro","svg","file-validation"],"backgroundTag":"invalid-svg-file","analyzedSha":"157c500c38faa7ecf1251adbaeefcd109470d75c","analyzedAt":"2026-08-18T18:48:03.901Z","contentChangedAt":"2026-08-18T18:48:03.901Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}