iOfficeAI/OfficeCLI · error · System.ArgumentException
Invalid JSON for 'runs': {jex.Message}
Error message
Invalid JSON for 'runs': {jex.Message} What it means
Thrown by ApplyRichTextToCell when the runs property is not valid JSON at all. JsonDocument.Parse raises a JsonException, which is caught and rewrapped as an ArgumentException with the parser's message. This fires before the array/object structure checks (492, 493), so any syntactically invalid JSON lands here.
Source
Thrown at src/officecli/Handlers/Excel/ExcelHandler.Add.Cells.cs:1466
{
var sv = p.Value.ValueKind switch
{
System.Text.Json.JsonValueKind.True => "true",
System.Text.Json.JsonValueKind.False => "false",
System.Text.Json.JsonValueKind.Null => "",
System.Text.Json.JsonValueKind.Number => p.Value.GetRawText(),
_ => p.Value.GetString() ?? ""
};
if (p.NameEquals("text")) text = sv;
else pd[p.Name] = sv;
}
OfficeCli.Core.ParseHelpers.ValidateXmlText(text, "richtext run text");
gatheredRuns.Add((text, pd));
}
}
catch (System.Text.Json.JsonException jex)
{
throw new ArgumentException($"Invalid JSON for 'runs': {jex.Message}");
}
}
else
{
var runKeys = properties.Keys
.Where(k => k.StartsWith("run", StringComparison.OrdinalIgnoreCase) && k.Length > 3 &&
int.TryParse(k.AsSpan(3), out _))
.OrderBy(k => int.Parse(k.AsSpan(3).ToString()))
.ToList();
foreach (var runKey in runKeys)
{
var runVal = properties[runKey];
var colonIdx = runVal.IndexOf(':');
string runText;
string[] runProps;
if (colonIdx >= 0)
{
runText = runVal[..colonIdx];View on GitHub (pinned to 1ced45e900)
Solutions
- If you meant legacy syntax, use run1=text:bold=true numbered keys instead of runs=.
- Validate the JSON with a linter before passing it; ensure double quotes and no trailing commas.
- Build the JSON with a serializer (System.Text.Json.JsonSerializer.Serialize) rather than hand-concatenating strings.
Example fix
// before props["runs"] = "text:Hello;bold:true"; // legacy syntax in wrong key // after props["run1"] = "text:Hello;bold=true"; // legacy numbered syntax
Defensive patterns
Strategy: try-catch
Validate before calling
if (props.TryGetValue("runs", out var runsJson) && !string.IsNullOrWhiteSpace(runsJson))
{
try { using var jdoc = System.Text.Json.JsonDocument.Parse(runsJson); }
catch (System.Text.Json.JsonException) { throw new InvalidOperationException("runs is not valid JSON"); }
}
handler.Add(parentPath, "richtext", pos, props); Type guard
static bool RunsJsonParses(string? json)
{
if (string.IsNullOrWhiteSpace(json)) return true;
try { using var _ = System.Text.Json.JsonDocument.Parse(json); return true; }
catch (System.Text.Json.JsonException) { return false; }
} Try / catch
try { handler.Add(parentPath, "richtext", pos, props); }
catch (ArgumentException ex) when (ex.Message.StartsWith("Invalid JSON for 'runs'"))
{ /* fix the JSON or switch to run1= legacy syntax */ } Prevention
- Build runs JSON with JsonSerializer.Serialize rather than string concatenation.
- If the input is legacy syntax (text:prop=val), use the run1= key instead of runs=.
- Run the JSON through a linter when accepting it from user input or a shell.
When it happens
Trigger: properties["runs"]="text:Hello;bold:true" (legacy syntax mistakenly put in runs=), or runs="{text" (truncated), or runs="'single quotes'". Any input that is not whitespace, not valid JSON, and not empty. Empty/whitespace runs skips the JSON branch entirely and falls to legacy runN parsing.
Common situations: User conflates the runs= JSON syntax with the legacy run1=text:prop=val syntax. Trailing commas, single quotes, unescaped quotes in the JSON. A shell quoting error that truncates the JSON.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- 'runs' must be a JSON array of run objects.
- Each run in 'runs' must be a JSON object.
- Parent path must be /SheetName/CellRef for adding a run
- Anchor sheet '{aSegs[0]}' must match target sheet '{colSheet
- Invalid 'outline' value: '{addColOutline}'. Expected an inte
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/5410d87b3d8a8c40.
Report an issue: GitHub.