iOfficeAI/OfficeCLI · error · InvalidDataException
Part '{part.Uri.OriginalString}' contains no root element (o
Error message
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. What it means
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.
Source
Thrown at src/officecli/Core/RawXmlHelper.cs:1257
$"declaration, whitespace, or BOM).");
return stripped;
}
finally
{
bclPkg.Close();
}
}
public static string ReadPartXml(OpenXmlPart part)
{
if (part.RootElement is OpenXmlPartRootElement root && root != null)
return root.OuterXml;
using var stream = part.GetStream(FileMode.Open, FileAccess.Read);
using var reader = new StreamReader(stream);
var content = reader.ReadToEnd();
var stripped = StripXmlProlog(content);
if (stripped.Length == 0)
throw new InvalidDataException(
$"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.");
return stripped;
}
private static string StripXmlProlog(string xml)
{
var s = xml.AsSpan().TrimStart();
// Loop: handle multiple stacked prologs / BOMs (defensive — input may
// be byte-concatenated from upstream tools or a corrupted package).
while (s.Length > 0)
{
// BOM (U+FEFF). StreamReader normally consumes it but we may be
// reading a re-encoded inner segment.
if (s[0] == '') { s = s[1..].TrimStart(); continue; }
// XML declaration: per spec must be `<?xml` followed by whitespaceView on GitHub (pinned to 1ced45e900)
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.
Defensive patterns
Strategy: try-catch
Validate before calling
// Inspect a part's stream length before trusting it
using var s = part.GetStream(FileMode.Open, FileAccess.Read);
using var r = new StreamReader(s);
var len = r.ReadToEnd().Trim().Length;
if (len == 0) throw new InvalidDataException($"Part {part.Uri} is empty; investigate corruption."); Try / catch
try { var xml = RawXmlHelper.ReadPartXml(part); }
catch (InvalidDataException ex) when (ex.Message.Contains("may be corrupt"))
{ /* do NOT treat as data — halt and investigate the package */ } Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Part '{target}' contains no root element (only an XML declar
- [Content_Types].xml is empty.
- Cannot {action} the document root element <{node.Name.LocalN
- invalid_input
- Unknown chart preset '{value}'. Available: {string.Join(", "
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/b20b7ac2ed9661ba.
Report an issue: GitHub.