{"record":{"id":"b20b7ac2ed9661ba","repo":"iOfficeAI/OfficeCLI","slug":"part-part-uri-originalstring-contains-no-root","errorCode":null,"errorMessage":"Part '{part.Uri.OriginalString}' contains no root element (only an XML declaration, whitespace, or BOM). The package may be corrupt; investigate before treating output as data.","messagePattern":"Part '(.+?)' contains no root element \\(only an XML declaration, whitespace, or BOM\\)\\. The package may be corrupt; investigate before treating output as data\\.","errorType":"exception","errorClass":"InvalidDataException","httpStatus":null,"severity":"error","filePath":"src/officecli/Core/RawXmlHelper.cs","lineNumber":1257,"sourceCode":"                    $\"declaration, whitespace, or BOM).\");\n            return stripped;\n        }\n        finally\n        {\n            bclPkg.Close();\n        }\n    }\n\n    public static string ReadPartXml(OpenXmlPart part)\n    {\n        if (part.RootElement is OpenXmlPartRootElement root && root != null)\n            return root.OuterXml;\n        using var stream = part.GetStream(FileMode.Open, FileAccess.Read);\n        using var reader = new StreamReader(stream);\n        var content = reader.ReadToEnd();\n        var stripped = StripXmlProlog(content);\n        if (stripped.Length == 0)\n            throw new InvalidDataException(\n                $\"Part '{part.Uri.OriginalString}' contains no root element \" +\n                $\"(only an XML declaration, whitespace, or BOM). The package \" +\n                $\"may be corrupt; investigate before treating output as data.\");\n        return stripped;\n    }\n\n    private static string StripXmlProlog(string xml)\n    {\n        var s = xml.AsSpan().TrimStart();\n        // Loop: handle multiple stacked prologs / BOMs (defensive — input may\n        // be byte-concatenated from upstream tools or a corrupted package).\n        while (s.Length > 0)\n        {\n            // BOM (U+FEFF). StreamReader normally consumes it but we may be\n            // reading a re-encoded inner segment.\n            if (s[0] == '﻿') { s = s[1..].TrimStart(); continue; }\n\n            // XML declaration: per spec must be `<?xml` followed by whitespace","sourceCodeStart":1239,"sourceCodeEnd":1275,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Core/RawXmlHelper.cs#L1239-L1275","documentation":"Thrown by ReadPartXml when an OpenXmlPart has no strongly-typed RootElement and its raw stream content strips down to nothing. The message explicitly warns the package may be corrupt and to investigate before treating output as data — distinguishing it from the milder zip-URI variants. InvalidDataException.","triggerScenarios":"Calling ReadPartXml on an untyped part (e.g. CustomXml) whose stream is empty, or on any OpenXmlPart whose RootElement is null and whose content is only a prolog/BOM/whitespace. ReadPartXml is reached from both the typed-part zip-URI path and direct part reads.","commonSituations":"A custom XML part was created but never populated, a package was corrupted in transit, or a part was written by a non-conformant tool. The 'investigate before treating output as data' wording signals a suspected integrity problem rather than a normal empty case.","solutions":["Inspect the part's bytes inside the zip to confirm corruption.","Rebuild or re-save the document so every part has a valid root element.","Do not catch-and-continue silently — the message flags potential corruption; log and halt for review."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Inspect a part's stream length before trusting it\nusing var s = part.GetStream(FileMode.Open, FileAccess.Read);\nusing var r = new StreamReader(s);\nvar len = r.ReadToEnd().Trim().Length;\nif (len == 0) throw new InvalidDataException($\"Part {part.Uri} is empty; investigate corruption.\");","typeGuard":null,"tryCatchPattern":"try { var xml = RawXmlHelper.ReadPartXml(part); }\ncatch (InvalidDataException ex) when (ex.Message.Contains(\"may be corrupt\"))\n{ /* do NOT treat as data — halt and investigate the package */ }","preventionTips":["Never silently continue past 'may be corrupt' — it is an explicit integrity warning.","Validate custom XML parts have a root element before read.","Log the part Uri to aid forensic review."],"tags":["raw-xml","ooxml","corrupt-package","invalid-data","custom-xml"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}