{"record":{"id":"885d13b14777a69f","repo":"DayuanJiang/next-ai-draw-io","slug":"svg-element-does-not-have-a-content-attribute","errorCode":null,"errorMessage":"SVG element does not have a 'content' attribute.","messagePattern":"SVG element does not have a 'content' attribute\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/utils.ts","lineNumber":1691,"sourceCode":"    }\n}\n\nexport function extractDiagramXML(xml_svg_string: string): string {\n    try {\n        // 1. Parse the SVG string (using built-in DOMParser in a browser-like environment)\n        const svgString = atob(xml_svg_string.slice(26))\n        const parser = new DOMParser()\n        const svgDoc = parser.parseFromString(svgString, \"image/svg+xml\")\n        const svgElement = svgDoc.querySelector(\"svg\")\n\n        if (!svgElement) {\n            throw new Error(\"No SVG element found in the input string.\")\n        }\n        // 2. Extract the 'content' attribute\n        const encodedContent = svgElement.getAttribute(\"content\")\n\n        if (!encodedContent) {\n            throw new Error(\"SVG element does not have a 'content' attribute.\")\n        }\n\n        // 3. Decode HTML entities (using a minimal function)\n        function decodeHtmlEntities(str: string) {\n            const textarea = document.createElement(\"textarea\") // Use built-in element\n            textarea.innerHTML = str\n            return textarea.value\n        }\n        const xmlContent = decodeHtmlEntities(encodedContent)\n\n        // 4. Parse the XML content\n        const xmlDoc = parser.parseFromString(xmlContent, \"text/xml\")\n        const diagramElement = xmlDoc.querySelector(\"diagram\")\n\n        if (!diagramElement) {\n            throw new Error(\"No diagram element found\")\n        }\n        // 5. Extract base64 encoded data","sourceCodeStart":1673,"sourceCodeEnd":1709,"githubUrl":"https://github.com/DayuanJiang/next-ai-draw-io/blob/155ef4f7acd29c9d46fb6fc35c92e6e6955a6ce1/lib/utils.ts#L1673-L1709","documentation":"The decoded SVG parsed successfully, but its root <svg> element has no 'content' attribute. draw.io's 'editable' SVG export embeds the original diagram XML (HTML-entity-encoded) in a content attribute specifically so it can be round-tripped back into the editor. This error means the SVG was exported without that embedded content — typically a plain final render.","triggerScenarios":"Calling the extract function on an SVG exported via 'File > Export as > SVG' without the 'Include a copy of the diagram' option, or on an SVG produced by another tool (Inkscape, Figma, hand-written).","commonSituations":"Users exporting 'clean' SVGs for production and then trying to programmatically recover the source diagram; SVGs that passed through optimizers (svgo) that strip unknown attributes; expecting lossless conversion from a plain SVG.","solutions":["Re-export from draw.io with 'Include a copy of the diagram' checked (embedImages/Editable SVG options)","If you still have the .drawio source file, use that XML instead of the SVG","Check svgElement.hasAttribute('content') before calling and fall back to asking the user for the source file","If an optimizer stripped it, recover the attribute from a pre-optimization copy"],"exampleFix":"// before\nconst xml = extractDiagramFromSvg(plainExportedSvg) // no content attr\n\n// after (guard first)\nconst doc = new DOMParser().parseFromString(atob(svg.slice(26)), 'image/svg+xml')\nif (!doc.querySelector('svg')?.hasAttribute('content')) throw new Error('re-export with embedded diagram')","handlingStrategy":"validation","validationCode":"const decoded = new DOMParser().parseFromString(atob(dataUri.slice(26)), 'image/svg+xml')\nconst svg = decoded.querySelector('svg')\nif (!svg?.hasAttribute('content')) throw new Error('svg lacks embedded diagram content; re-export with \"Include a copy of the diagram\"')","typeGuard":"function hasEmbeddedContent(svg: Element): boolean {\n  return Boolean(svg.getAttribute('content')?.trim())\n}","tryCatchPattern":"try { extract(dataUri) } catch (e) { if ((e as Error).message.includes(\"'content' attribute\")) fallbackToSourceFile() }","preventionTips":["Enable 'Include a copy of the diagram' when exporting SVG from draw.io","Keep the original .drawio file as the source of truth","Exclude draw.io SVGs from svgo/attribute-stripping optimizers"],"tags":["svg","drawio","missing-attribute","export-options"],"backgroundTag":"missing-required-attribute","analyzedSha":"155ef4f7acd29c9d46fb6fc35c92e6e6955a6ce1","analyzedAt":"2026-08-27T11:40:38.297Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}