{"record":{"id":"487cfefc5b5c7ad4","repo":"can1357/oh-my-pi","slug":"invalid-xml-unterminated-cdata-section","errorCode":null,"errorMessage":"Invalid XML: unterminated CDATA section","messagePattern":"Invalid XML: unterminated CDATA section","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/utils/src/docx/xml.ts","lineNumber":77,"sourceCode":"\t\tconst lessThan = source.indexOf(\"<\", offset);\n\t\tif (lessThan === -1) {\n\t\t\tconst value = decodeEntities(source.slice(offset));\n\t\t\tif (value) stack[stack.length - 1].children.push({ kind: \"text\", value });\n\t\t\tbreak;\n\t\t}\n\t\tif (lessThan > offset) {\n\t\t\tconst value = decodeEntities(source.slice(offset, lessThan));\n\t\t\tif (value) stack[stack.length - 1].children.push({ kind: \"text\", value });\n\t\t}\n\t\tif (source.startsWith(\"<!--\", lessThan)) {\n\t\t\tconst end = source.indexOf(\"-->\", lessThan + 4);\n\t\t\tif (end === -1) throw new Error(\"Invalid XML: unterminated comment\");\n\t\t\toffset = end + 3;\n\t\t\tcontinue;\n\t\t}\n\t\tif (source.startsWith(\"<![CDATA[\", lessThan)) {\n\t\t\tconst end = source.indexOf(\"]]>\", lessThan + 9);\n\t\t\tif (end === -1) throw new Error(\"Invalid XML: unterminated CDATA section\");\n\t\t\tstack[stack.length - 1].children.push({ kind: \"text\", value: source.slice(lessThan + 9, end) });\n\t\t\toffset = end + 3;\n\t\t\tcontinue;\n\t\t}\n\t\tif (source.startsWith(\"<?\", lessThan)) {\n\t\t\tconst end = source.indexOf(\"?>\", lessThan + 2);\n\t\t\tif (end === -1) throw new Error(\"Invalid XML: unterminated processing instruction\");\n\t\t\toffset = end + 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (source.startsWith(\"<!\", lessThan)) {\n\t\t\tconst end = source.indexOf(\">\", lessThan + 2);\n\t\t\tif (end === -1) throw new Error(\"Invalid XML: unterminated declaration\");\n\t\t\toffset = end + 1;\n\t\t\tcontinue;\n\t\t}\n\t\tconst end = source.indexOf(\">\", lessThan + 1);\n\t\tif (end === -1) throw new Error(\"Invalid XML: unterminated tag\");","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/docx/xml.ts#L59-L95","documentation":"The XML parser handles \"<![CDATA[ ... ]]>\" sections as raw text. When a CDATA opener lacks its closing \"]]>\" before end-of-input, the parser cannot determine the section boundary and throws this error from parseXml.","triggerScenarios":"Calling parseXml() (directly or via convertToHtml) on XML with \"<![CDATA[\" without a closing \"]]>\" — truncated files, generated XML with unterminated CDATA, or content containing literal \"]]>\" handling mistakes that ate the closer.","commonSituations":"Escaped code/sample text embedded in DOCX documents where the closing bracket was lost in preprocessing; XML assembled by concatenation that dropped the terminator; truncated entries in a damaged archive.","solutions":["Ensure every \"<![CDATA[\" section ends with \"]]>\" in the source XML.","Re-extract or re-download the file — verify the XML part isn't truncated.","If embedding arbitrary text, escape XML entities instead of relying on CDATA, or split text containing \"]]>\" across two CDATA sections.","Validate the XML part with a strict parser before feeding it to the converter to get a clearer diagnostic."],"exampleFix":"// before\nconst xml = `<doc><![CDATA[ 1 < 2 `;\nparseXml(xml); // throws\n\n// after\nconst xml = `<doc><![CDATA[ 1 < 2 ]]></doc>`;\nparseXml(xml);","handlingStrategy":"validation","validationCode":"function hasUnterminatedCdata(xml: string): boolean {\n  return (xml.match(/<!\\[CDATA\\[/g)?.length ?? 0) > (xml.match(/\\]\\]>/g)?.length ?? 0);\n}\nif (hasUnterminatedCdata(xml)) throw new Error(\"XML has an unterminated CDATA section\");","typeGuard":null,"tryCatchPattern":"try {\n  const doc = parseXml(xml);\n} catch (err) {\n  if (err instanceof Error && err.message === \"Invalid XML: unterminated CDATA section\") {\n    // reject the document or repair by appending \"]]>\" before the next tag\n  } else throw err;\n}","preventionTips":["Escape text with entities (&lt;, &amp;) instead of CDATA when possible.","Split any content containing \"]]>\" into adjacent CDATA sections: `...]]]]><![CDATA[>...`.","Verify files aren't truncated before parsing.","Run a strict XML validation pass before feeding documents to the converter."],"tags":["xml","parsing","docx","malformed-input"],"backgroundTag":"malformed-xml","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}