iOfficeAI/OfficeCLI · error · ArgumentException

comment runs: invalid JSON array — {ex.Message}

Error message

comment runs: invalid JSON array — {ex.Message}

What it means

Thrown by BuildCommentTextFromRuns when JsonNode.Parse raises a JsonException on the `runs=<json>` value for a comment. The runs value must be a parseable JSON string; any malformed JSON (missing quotes, trailing comma, unescaped char) bubbles up wrapped as an ArgumentException with the parser's message.

Source

Thrown at src/officecli/Handlers/Excel/ExcelHandler.Helpers.Node.cs:979

            // Non-generic Add(JsonNode) — the generic Add<T> overload carries
            // RequiresUnreferencedCode (IL2026) though it never serializes a JsonNode.
            arr.Add((System.Text.Json.Nodes.JsonNode)o);
        }
        return arr.ToJsonString();
    }

    // Build a CommentText from a `runs=<json array>` value, one <r> per run
    // carrying its own <rPr>. Run vocabulary mirrors rich-text cells
    // (bold/italic/strike/underline/superscript/subscript/size/color/font) so
    // the two paths share one input contract. Comment runs keep the Tahoma-9
    // indexed-81 default for facets a run leaves unspecified.
    internal static CommentText BuildCommentTextFromRuns(string runsJson)
    {
        System.Text.Json.Nodes.JsonArray? arr;
        try { arr = System.Text.Json.Nodes.JsonNode.Parse(runsJson) as System.Text.Json.Nodes.JsonArray; }
        catch (System.Text.Json.JsonException ex)
        {
            throw new ArgumentException($"comment runs: invalid JSON array — {ex.Message}");
        }
        if (arr == null)
            throw new ArgumentException("comment runs: value must be a JSON array");

        var ct = new CommentText();
        foreach (var item in arr)
        {
            if (item is not System.Text.Json.Nodes.JsonObject o) continue;
            var text = o["text"]?.GetValue<string>() ?? "";
            OfficeCli.Core.ParseHelpers.ValidateXmlText(text, "comment run text");

            var rPr = new RunProperties();
            bool RunBool(string key) => o[key] is { } n
                && (n.GetValueKind() == System.Text.Json.JsonValueKind.True
                    || (n.GetValueKind() == System.Text.Json.JsonValueKind.String && IsTruthy(n.GetValue<string>())));

            if (RunBool("bold")) rPr.AppendChild(new Bold());
            if (RunBool("italic")) rPr.AppendChild(new Italic());

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Validate the runs string parses as JSON before sending it (JsonNode.Parse or json.loads in the caller).
  2. Build the runs array with a JSON serializer (System.Text.Json.JsonSerializer.Serialize or json.dumps), never string concatenation.
  3. Check the parser message in the exception text — it pinpoints the byte offset of the syntax error.

Example fix

// before
string runs = "[{\"text\":\"hi\"},]"; // trailing comma
BuildCommentTextFromRuns(runs);
// after
var runsObj = new[] { new { text = "hi" } };
string runs = System.Text.Json.JsonSerializer.Serialize(runsObj);
BuildCommentTextFromRuns(runs);
Defensive patterns

Strategy: validation

Validate before calling

// Validate before the API call
static bool IsValidRunsJson(string runsJson)
{
    try { using var doc = System.Text.Json.JsonDocument.Parse(runsJson); return doc.RootElement.ValueKind == System.Text.Json.JsonValueKind.Array; }
    catch { return false; }
}

Type guard

null

Try / catch

try
{
    BuildCommentTextFromRuns(runs);
}
catch (ArgumentException ex) when (ex.Message.StartsWith("comment runs: invalid JSON"))
{
    // surface parser offset to the user; do not retry with the same string
}

Prevention

When it happens

Trigger: Calling the comment API with runs='[{"text":"hi"},]' (trailing comma), runs='{text:1}' (single quotes), or any non-JSON text. JsonNode.Parse throws JsonException, caught and rethrown as ArgumentException.

Common situations: Generating runs JSON by string concatenation instead of a serializer; passing a Python/JS dict literal instead of JSON; shell quoting that strips double quotes around keys.

Understand the failure class

Related errors


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