{"record":{"id":"5e996fe813692d3e","repo":"iOfficeAI/OfficeCLI","slug":"invalid-value-5e996f","errorCode":"invalid_value","errorMessage":"{fieldName}: contains character invalid in XML 1.0 text ({problem}). Allowed: U+0009 (tab), U+000A (newline), U+000D (carriage return), and U+0020 and above (excluding surrogate code points and U+FFFE/U+FFFF).","messagePattern":"(.+?): contains character invalid in XML 1\\.0 text \\((.+?)\\)\\. Allowed: U\\+0009 \\(tab\\), U\\+000A \\(newline\\), U\\+000D \\(carriage return\\), and U\\+0020 and above \\(excluding surrogate code points and U\\+FFFE/U\\+FFFF\\)\\.","errorType":"exception","errorClass":"CliException","httpStatus":null,"severity":"error","filePath":"src/officecli/Core/XmlTextValidator.cs","lineNumber":83,"sourceCode":"        return null;\n    }\n\n    /// <summary>\n    /// Throws <see cref=\"CliException\"/> with code `invalid_value` when\n    /// <paramref name=\"text\"/> contains a character forbidden in XML 1.0\n    /// character data. <paramref name=\"fieldName\"/> appears in the error\n    /// message to help callers identify which input was rejected.\n    /// </summary>\n    public static void ValidateOrThrow(string? text, string fieldName, bool allowSoftBreakChar = false)\n    {\n        // NEWLINE-SEMANTICS-V2: '\\v' (U+000B) is XML-illegal, but text\n        // pipelines that split it into <a:br/> / <w:br/> ELEMENTS before\n        // serialization (AppendLineWithTabs / AppendTextWithBreaks) may\n        // opt in — the char never reaches XML character data there.\n        var probe = allowSoftBreakChar ? text?.Replace(\"\\v\", \"\") : text;\n        var problem = FindInvalidChar(probe);\n        if (problem is null) return;\n        throw new CliException(\n            $\"{fieldName}: contains character invalid in XML 1.0 text ({problem}). \" +\n            \"Allowed: U+0009 (tab), U+000A (newline), U+000D (carriage return), and U+0020 and above \" +\n            \"(excluding surrogate code points and U+FFFE/U+FFFF).\")\n        {\n            Code = \"invalid_value\",\n        };\n    }\n\n    private static string FormatOffender(int cp, int offset)\n        => $\"U+{cp.ToString(\"X4\", CultureInfo.InvariantCulture)} at offset {offset}\";\n}\n","sourceCodeStart":65,"sourceCodeEnd":95,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Core/XmlTextValidator.cs#L65-L95","documentation":"Thrown by XmlTextValidator.ValidateOrThrow when user-supplied text contains a character that is illegal in XML 1.0 character data. Open XML files (.docx/.xlsx/.pptx) are serialized as XML 1.0, so codepoints outside the allowed set (U+0009, U+000A, U+000D, U+0020–U+D7FF, U+E000–U+FFFD, U+10000–U+10FFFF via surrogate pairs) would cause XmlException at save time — which would leak as an internal_error and poison the in-memory document. This validator runs at every Add/Set entry point that accepts free-form text, catching the problem early with a deterministic, user-fixable CliException (code=invalid_value).","triggerScenarios":"Passing a string containing control characters such as NUL (U+0000), BEL (U+0007), vertical tab (U+000B, unless allowSoftBreakChar=true), form feed (U+000C), or unpaired surrogate code units. The offending codepoint and its byte offset are reported. Common when text originates from a database column, a clipboard paste, or an LLM-generated value that includes a stray control character.","commonSituations":"Copying text from a terminal or binary file that includes ANSI control codes; an API consumer sending a JSON string with embedded \\u0000 (common from JavaScript/Node which allows NUL in strings); an LLM model emitting a U+000B vertical tab as a 'soft line break' (the allowSoftBreakChar opt-in exists specifically for this pipeline); a copy-paste from a PDF that includes form-feed or other formatting control characters.","solutions":["Sanitize the input string before passing it to the API: strip or replace characters outside the XML 1.0 range.","If the character is a vertical tab (U+000B) intended as a soft line break, check whether the calling pipeline supports allowSoftBreakChar=true (used by AppendLineWithTabs / AppendTextWithBreaks which split it into <w:br/> elements).","Replace NUL bytes with nothing or a space: text.Replace(\"\\0\", \"\") before the call.","If the text comes from an external source (HTTP, DB, LLM), add a sanitization filter at the ingestion boundary."],"exampleFix":"// before: raw text from an external source may contain control chars\nhandler.Add(\"/paragraph\", new { text = userInput });\n\n// after: sanitize before the call\nvar clean = new StringBuilder();\nforeach (var c in userInput)\n    if (c == '\\t' || c == '\\n' || c == '\\r' || c >= 0x20)\n        clean.Append(c);\nhandler.Add(\"/paragraph\", new { text = clean.ToString() });","handlingStrategy":"validation","validationCode":"// Sanitize text before passing to any Add/Set API\nstatic string SanitizeForXml(string? text)\n{\n    if (string.IsNullOrEmpty(text)) return text ?? \"\";\n    var sb = new StringBuilder(text.Length);\n    foreach (var c in text)\n    {\n        if (c == '\\t' || c == '\\n' || c == '\\r' || (c >= 0x20 && c <= 0xD7FF) || (c >= 0xE000 && c <= 0xFFFD))\n            sb.Append(c);\n    }\n    return sb.ToString();\n}","typeGuard":"// Type guard: returns null if text is XML-1.0-safe, otherwise the first offender\nstatic string? XmlCharProblem(string? text)\n    => OfficeCli.Core.XmlTextValidator.FindInvalidChar(text);","tryCatchPattern":"try\n{\n    handler.Add(\"/paragraph\", new { text = userInput });\n}\ncatch (CliException ex) when (ex.Code == \"invalid_value\" && ex.Message.Contains(\"invalid in XML 1.0\"))\n{\n    // Input contained illegal control characters — sanitize and retry\n    var sanitized = SanitizeForXml(userInput);\n    handler.Add(\"/paragraph\", new { text = sanitized });\n}","preventionTips":["Sanitize all external text (HTTP, DB, LLM, clipboard) at the ingestion boundary before it reaches document APIs.","Strip NUL bytes explicitly: text.Replace(\"\\0\", \"\") — JavaScript/Node commonly allow NUL in strings.","Use XmlTextValidator.FindInvalidChar as a pre-check when you need to know if text is safe without throwing.","For vertical-tab soft breaks, pass allowSoftBreakChar=true only in pipelines that convert \\v to <br/> elements before serialization."],"tags":["xml-validation","text-sanitization","open-xml","invalid-value","input-validation"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}