iOfficeAI/OfficeCLI · error · CliException
invalid_input
invalid_input
Error message
path contains a NUL byte (\u0000), which is invalid in OOXML.
What it means
Thrown by ExecuteBatchItem at the batch boundary when item.Path contains a U+0000 (NUL) byte. OOXML XML writers throw a System.Xml.XmlException on NUL deep inside the SDK Save path, AFTER earlier batch items have already mutated the document, which would lose every subsequent mutation in the session. Rejecting up front records exactly one failed step and keeps the rest of the document intact. CliException Code="invalid_input".
Source
Thrown at src/officecli/CommandBuilder.cs:916
}
internal static string ExecuteBatchItem(OfficeCli.Core.IDocumentHandler handler, BatchItem item, bool json)
{
var format = json ? OfficeCli.Core.OutputFormat.Json : OfficeCli.Core.OutputFormat.Text;
var props = item.Props ?? new Dictionary<string, string>();
// Reject null bytes (U+0000) anywhere in caller-controlled strings —
// path, selector, text, and prop values. OOXML xml writers throw
// System.Xml.XmlException ("'.', hexadecimal value 0x00, is an
// invalid character.") deep inside the SDK's Save path, AFTER prior
// batch items have already mutated the document. The exception
// bubbles up past the handler's Save and leaves the resident in a
// state where the next close throws again — silently losing every
// successful mutation in the same session. Reject at the boundary
// with a stable code so the batch driver records ONE failed step
// and keeps the rest of the document intact.
if (ContainsNullByte(item.Path))
throw new CliException($"path contains a NUL byte (\\u0000), which is invalid in OOXML.")
{ Code = "invalid_input" };
if (ContainsNullByte(item.Selector))
throw new CliException($"selector contains a NUL byte (\\u0000), which is invalid in OOXML.")
{ Code = "invalid_input" };
if (ContainsNullByte(item.Text))
throw new CliException($"text contains a NUL byte (\\u0000), which is invalid in OOXML.")
{ Code = "invalid_input" };
foreach (var (pk, pv) in props)
{
if (ContainsNullByte(pk) || ContainsNullByte(pv))
throw new CliException($"prop '{pk}' contains a NUL byte (\\u0000), which is invalid in OOXML.")
{ Code = "invalid_input" };
}
switch (item.Command.ToLowerInvariant())
{
// NEWLINE-SEMANTICS-V2: version-stamp items are normally stripped
// by BatchCompat.PrepareForReplay; tolerate one that reaches theView on GitHub (pinned to 1ced45e900)
Solutions
- Sanitize every caller-controlled string: strip or replace NUL bytes before building the batch item.
- Validate source data encoding (treat NUL as a fatal input error at ingest).
- For path values, replace '\u0000' with an empty string or reject the whole payload.
- Add a pre-submission assertion that no field contains '\u0000'.
Example fix
// before
{"command":"set","path":"/\u0000slide[1]","props":{"bold":"true"}}
// after
{"command":"set","path":"/slide[1]","props":{"bold":"true"}} Defensive patterns
Strategy: validation
Validate before calling
static string Sanitize(string? s) => (s ?? "").Replace("\u0000", "");
item.Path = Sanitize(item.Path);
if (item.Path.Contains('\u0000')) throw new ArgumentException("path has NUL"); Prevention
- Sanitize every caller-controlled string at the trust boundary.
- Treat NUL as a fatal input error at ingest, not at OOXML save time.
- Pre-scan the whole batch payload for '\u0000' before submission.
When it happens
Trigger: {"command":"set","path":"/\u0000slide[1]","props":{"bold":"true"}}; a path string assembled from a C-style NUL-terminated buffer; binary/external data sourcing that injects control characters.
Common situations: Pasting data sourced from binary protocols or legacy systems; an upstream bug that embeds NUL terminators; NDJSON plugin emitting raw bytes; templating that interpolated an uninitialized/null-terminated string field.
Related errors
- Path not found: {path}
- 'query' command requires 'selector' field. Example: {"comman
- 'set' command requires 'path' field. Example: {"command": "s
- 'set' command requires 'props' field with at least one key=v
- unsupported_property
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/781bdde888a323a3.
Report an issue: GitHub.