iOfficeAI/OfficeCLI · warning · JsonException
Unexpected end of JSON
Error message
Unexpected end of JSON
What it means
JsonException from the ARRAY branch of LenientStringDictionaryConverter.Read: the JSON stream ended (reader returned false / ran out of bytes) before the closing ] of the props array was seen. This is a truncated/malformed payload, not a value-type problem.
Source
Thrown at src/officecli/BatchTypes.cs:33
// Array form: ["key=value", ...]. This mirrors the single-command MCP
// `props` argument and the CLI `--prop key=value` flag, so an agent that
// learned props from `set`/`add` produces the same shape inside a batch
// item. Before this, batch props was object-only and every array-form
// batch failed with "Expected object for props" — observed as a 100%
// batch-failure for models that (correctly) reused the single-command
// props shape. Lenient split on the first '=' matches McpServer.ParseProps.
if (reader.TokenType == JsonTokenType.StartArray)
{
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndArray) return dict;
if (reader.TokenType != JsonTokenType.String)
throw new JsonException("Expected \"key=value\" string in props array");
var kv = reader.GetString()!;
var eq = kv.IndexOf('=');
if (eq > 0) dict[kv[..eq]] = kv[(eq + 1)..]; // skip malformed, as ParseProps does
}
throw new JsonException("Unexpected end of JSON");
}
if (reader.TokenType != JsonTokenType.StartObject)
throw new JsonException("Expected object or [\"key=value\"] array for props");
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndObject) return dict;
if (reader.TokenType != JsonTokenType.PropertyName)
throw new JsonException("Expected property name");
var key = reader.GetString()!;
reader.Read();
var value = reader.TokenType switch
{
JsonTokenType.String => reader.GetString()!,
JsonTokenType.Number => reader.TryGetInt64(out var l) ? l.ToString() : reader.GetDouble().ToString(),
JsonTokenType.True => "true",
JsonTokenType.False => "false",
JsonTokenType.Null => "",
_ => throw new JsonException($"Unexpected token {reader.TokenType} for prop value '{key}'")View on GitHub (pinned to 1ced45e900)
Solutions
- Validate the batch JSON parses fully (JSON.parse on the client) before sending.
- Ensure the payload is not truncated by a body-size limit on the resident/MCP transport.
- Build batch JSON with a real serializer rather than manual string concatenation.
Example fix
// before: batchJson string ends mid-array: ..."props":["a=1","b=2"
// after: produce complete, validated JSON
const items = [{ command:'set', path:'/A1', props:['a=1','b=2'] }];
const batchJson = JSON.stringify(items); // always well-formed Defensive patterns
Strategy: validation
Validate before calling
// Validate the whole batch payload parses end-to-end before sending const items = buildItems(); const batchJson = JSON.stringify(items); JSON.parse(batchJson); // throws here if truncated/malformed — fail before the resident does await doc.batch(items);
Prevention
- Build batch JSON with JSON.stringify, never hand-concatenated strings.
- Check the resident/MCP transport max body size and chunk large batches.
- Round-trip parse your payload as a smoke test in dev.
When it happens
Trigger: A batch JSON string cut off mid-array (network truncation, buffer limit, string concatenation bug); a streaming deserializer that stopped early; an unterminated props array.
Common situations: Sending a very large batch whose JSON was truncated by a size cap; building batchJson via string slicing that dropped the tail; copy/paste of a partial JSON example.
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
- Expected "key=value" string in props array
- Expected object or ["key=value"] array for props
- Expected property name
- Unexpected token {reader.TokenType} for prop value '{key}'
- Expected StartObject for BatchItem
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/983afca12a63c7e7.
Report an issue: GitHub.