{"record":{"id":"781bdde888a323a3","repo":"iOfficeAI/OfficeCLI","slug":"invalid-input","errorCode":"invalid_input","errorMessage":"path contains a NUL byte (\\u0000), which is invalid in OOXML.","messagePattern":"path contains a NUL byte \\(\\\\u0000\\), which is invalid in OOXML\\.","errorType":"exception","errorClass":"CliException","httpStatus":null,"severity":"error","filePath":"src/officecli/CommandBuilder.cs","lineNumber":916,"sourceCode":"    }\n\n    internal static string ExecuteBatchItem(OfficeCli.Core.IDocumentHandler handler, BatchItem item, bool json)\n    {\n        var format = json ? OfficeCli.Core.OutputFormat.Json : OfficeCli.Core.OutputFormat.Text;\n        var props = item.Props ?? new Dictionary<string, string>();\n\n        // Reject null bytes (U+0000) anywhere in caller-controlled strings —\n        // path, selector, text, and prop values. OOXML xml writers throw\n        // System.Xml.XmlException (\"'.', hexadecimal value 0x00, is an\n        // invalid character.\") deep inside the SDK's Save path, AFTER prior\n        // batch items have already mutated the document. The exception\n        // bubbles up past the handler's Save and leaves the resident in a\n        // state where the next close throws again — silently losing every\n        // successful mutation in the same session. Reject at the boundary\n        // with a stable code so the batch driver records ONE failed step\n        // and keeps the rest of the document intact.\n        if (ContainsNullByte(item.Path))\n            throw new CliException($\"path contains a NUL byte (\\\\u0000), which is invalid in OOXML.\")\n                { Code = \"invalid_input\" };\n        if (ContainsNullByte(item.Selector))\n            throw new CliException($\"selector contains a NUL byte (\\\\u0000), which is invalid in OOXML.\")\n                { Code = \"invalid_input\" };\n        if (ContainsNullByte(item.Text))\n            throw new CliException($\"text contains a NUL byte (\\\\u0000), which is invalid in OOXML.\")\n                { Code = \"invalid_input\" };\n        foreach (var (pk, pv) in props)\n        {\n            if (ContainsNullByte(pk) || ContainsNullByte(pv))\n                throw new CliException($\"prop '{pk}' contains a NUL byte (\\\\u0000), which is invalid in OOXML.\")\n                    { Code = \"invalid_input\" };\n        }\n\n        switch (item.Command.ToLowerInvariant())\n        {\n            // NEWLINE-SEMANTICS-V2: version-stamp items are normally stripped\n            // by BatchCompat.PrepareForReplay; tolerate one that reaches the","sourceCodeStart":898,"sourceCodeEnd":934,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/CommandBuilder.cs#L898-L934","documentation":"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\".","triggerScenarios":"{\"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.","commonSituations":"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.","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'."],"exampleFix":"// before\n{\"command\":\"set\",\"path\":\"/\\u0000slide[1]\",\"props\":{\"bold\":\"true\"}}\n// after\n{\"command\":\"set\",\"path\":\"/slide[1]\",\"props\":{\"bold\":\"true\"}}","handlingStrategy":"validation","validationCode":"static string Sanitize(string? s) => (s ?? \"\").Replace(\"\\u0000\", \"\");\nitem.Path = Sanitize(item.Path);\nif (item.Path.Contains('\\u0000')) throw new ArgumentException(\"path has NUL\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["ooxml","batch","validation","nul-byte","invalid-input","officecli"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}