iOfficeAI/OfficeCLI · error · CliException

invalid_value

invalid_value

Error message

{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).

What it means

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).

Source

Thrown at src/officecli/Core/XmlTextValidator.cs:83

        return null;
    }

    /// <summary>
    /// Throws <see cref="CliException"/> with code `invalid_value` when
    /// <paramref name="text"/> contains a character forbidden in XML 1.0
    /// character data. <paramref name="fieldName"/> appears in the error
    /// message to help callers identify which input was rejected.
    /// </summary>
    public static void ValidateOrThrow(string? text, string fieldName, bool allowSoftBreakChar = false)
    {
        // NEWLINE-SEMANTICS-V2: '\v' (U+000B) is XML-illegal, but text
        // pipelines that split it into <a:br/> / <w:br/> ELEMENTS before
        // serialization (AppendLineWithTabs / AppendTextWithBreaks) may
        // opt in — the char never reaches XML character data there.
        var probe = allowSoftBreakChar ? text?.Replace("\v", "") : text;
        var problem = FindInvalidChar(probe);
        if (problem is null) return;
        throw new CliException(
            $"{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).")
        {
            Code = "invalid_value",
        };
    }

    private static string FormatOffender(int cp, int offset)
        => $"U+{cp.ToString("X4", CultureInfo.InvariantCulture)} at offset {offset}";
}

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Sanitize the input string before passing it to the API: strip or replace characters outside the XML 1.0 range.
  2. 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).
  3. Replace NUL bytes with nothing or a space: text.Replace("\0", "") before the call.
  4. If the text comes from an external source (HTTP, DB, LLM), add a sanitization filter at the ingestion boundary.

Example fix

// before: raw text from an external source may contain control chars
handler.Add("/paragraph", new { text = userInput });

// after: sanitize before the call
var clean = new StringBuilder();
foreach (var c in userInput)
    if (c == '\t' || c == '\n' || c == '\r' || c >= 0x20)
        clean.Append(c);
handler.Add("/paragraph", new { text = clean.ToString() });
Defensive patterns

Strategy: validation

Validate before calling

// Sanitize text before passing to any Add/Set API
static string SanitizeForXml(string? text)
{
    if (string.IsNullOrEmpty(text)) return text ?? "";
    var sb = new StringBuilder(text.Length);
    foreach (var c in text)
    {
        if (c == '\t' || c == '\n' || c == '\r' || (c >= 0x20 && c <= 0xD7FF) || (c >= 0xE000 && c <= 0xFFFD))
            sb.Append(c);
    }
    return sb.ToString();
}

Type guard

// Type guard: returns null if text is XML-1.0-safe, otherwise the first offender
static string? XmlCharProblem(string? text)
    => OfficeCli.Core.XmlTextValidator.FindInvalidChar(text);

Try / catch

try
{
    handler.Add("/paragraph", new { text = userInput });
}
catch (CliException ex) when (ex.Code == "invalid_value" && ex.Message.Contains("invalid in XML 1.0"))
{
    // Input contained illegal control characters — sanitize and retry
    var sanitized = SanitizeForXml(userInput);
    handler.Add("/paragraph", new { text = sanitized });
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13). Data as JSON: /api/errors/5e996fe813692d3e. Report an issue: GitHub.