iOfficeAI/OfficeCLI · error · ArgumentException
{propName} contains XML-illegal control character U+{(int)c:
Error message
{propName} contains XML-illegal control character U+{(int)c:X4} at position {i}. Allowed control chars: \t, \n, \r{allowSoftBreakChar ? ", \v." : "."} What it means
Thrown by ParseHelpers.ValidateXmlText when the value contains an XML 1.0 illegal control character (U+0000–U+0008, U+000B, U+000C, U+000E–U+001F). Only \t, \n, \r are always allowed; \v (U+000B) is allowed only when allowSoftBreakChar=true (callers that turn it into a <w:br/> before serialization). This pre-validates so the OOXML serializer does not fail later at save time with a data-loss message.
Source
Thrown at src/officecli/Core/ParseHelpers.cs:851
/// (U+D800–U+DFFF without a matching pair), and the U+FFFE / U+FFFF
/// noncharacters.
/// </summary>
public static void ValidateXmlText(string? value, string propName, bool allowSoftBreakChar = false)
{
if (value == null) return;
for (int i = 0; i < value.Length; i++)
{
char c = value[i];
if (c == '\t' || c == '\n' || c == '\r') continue;
// '\v' (0x0B) is XML-illegal as character data. It is allowed ONLY
// when the caller consumes it into a break ELEMENT before
// serialization (NEWLINE-SEMANTICS-V2: AppendTextWithBreaks turns
// '\v' into <w:br/>). Callers that write validated text verbatim
// into XML (chart titles, xlsx cell values, headers, ...) keep the
// strict default so '\v' can never reach raw character data.
if (c == '\v' && allowSoftBreakChar) continue;
if (c < 0x20)
throw new ArgumentException(
$"{propName} contains XML-illegal control character U+{(int)c:X4} at position {i}. " +
"Allowed control chars: \\t, \\n, \\r" +
(allowSoftBreakChar ? ", \\v." : "."));
// UTF-16 surrogates only valid in pairs (high then low). A lone
// half is illegal in XML 1.0 character data.
if (char.IsHighSurrogate(c))
{
if (i + 1 >= value.Length || !char.IsLowSurrogate(value[i + 1]))
throw new ArgumentException(
$"{propName} contains an unpaired high surrogate U+{(int)c:X4} at position {i}. Use a complete UTF-16 surrogate pair.");
i++; // skip the matched low surrogate
continue;
}
if (char.IsLowSurrogate(c))
throw new ArgumentException(
$"{propName} contains an unpaired low surrogate U+{(int)c:X4} at position {i}. Use a complete UTF-16 surrogate pair.");
if (c == 0xFFFE || c == 0xFFFF)
throw new ArgumentException(View on GitHub (pinned to 1ced45e900)
Solutions
- Strip or replace control characters (except \t \n \r) before setting the value.
- If the field is a Word body-text path that supports soft breaks, ensure the caller passes allowSoftBreakChar=true and uses \v intentionally for <w:br/>.
- Sanitize upstream (e.g. regex replace [\x00-\x08\x0B\x0C\x0E-\x1F] with '' or a space).
Example fix
// before text="line1\x00line2" // after text="line1line2" // control char stripped
Defensive patterns
Strategy: validation
Validate before calling
// Strip XML-illegal C0 control chars (keep \t \n \r; allow \v only if caller will convert it):
static string SanitizeForXml(string s, bool keepVerticalTab = false)
=> System.Text.RegularExpressions.Regex.Replace(s,
keepVerticalTab ? @"[\x00-\x08\x0C\x0E-\x1F]" : @"[\x00-\x08\x0B\x0C\x0E-\x1F]",
string.Empty); Prevention
- Sanitize text from terminals/databases to remove C0 control bytes.
- Only pass allowSoftBreakChar=true on paths that convert \v to a break element.
- Validate before setting so save-time data-loss errors never occur.
When it happens
Trigger: Setting any text that flows verbatim into XML character data — chart/axis titles, cell values, headers/footers, comments, bookmarks, field instructions, hyperlinks, image alt text, number format codes — and the string contains a raw control char like a NUL (U+0000), BEL (U+0007), or a vertical tab \v when the caller kept the strict default.
Common situations: Pasting text from a terminal/database that contains NUL or other C0 control bytes; embedded \v (vertical tab) in a field that does not convert it to a break element; binary-ish data leaking into a text field; a stray ESC (U+001B) from ANSI-stripped output.
Related errors
- {propName} contains an unpaired high surrogate U+{(int)c:X4}
- {propName} contains an unpaired low surrogate U+{(int)c:X4}
- {propName} contains the XML-illegal noncharacter U+{(int)c:X
- Invalid '{propertyName}' value '{value}': degrees must be in
- Invalid color value: '{value}'. Expected 6-digit hex RGB (e.
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/d8399ab564126582.
Report an issue: GitHub.