iOfficeAI/OfficeCLI · warning · JsonException
Expected StartObject for BatchItem
Error message
Expected StartObject for BatchItem
What it means
JsonException from BatchItemConverter.Read: an element of the batch list is not a JSON object. Each batch item must be a StartObject (e.g. {command:'set', ...}); a bare string, number, boolean, array, or null as a list element is rejected here.
Source
Thrown at src/officecli/BatchTypes.cs:74
}
public override void Write(Utf8JsonWriter writer, Dictionary<string, string> value, JsonSerializerOptions options)
{
writer.WriteStartObject();
foreach (var kv in value)
writer.WriteString(kv.Key, kv.Value);
writer.WriteEndObject();
}
}
internal class BatchItemConverter : JsonConverter<BatchItem>
{
private static readonly LenientStringDictionaryConverter PropsConverter = new();
public override BatchItem? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.StartObject)
throw new JsonException("Expected StartObject for BatchItem");
var item = new BatchItem();
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndObject) return item;
if (reader.TokenType != JsonTokenType.PropertyName)
throw new JsonException("Expected PropertyName");
var prop = reader.GetString()!;
reader.Read();
switch (prop.ToLowerInvariant())
{
case "command":
case "op":
item.Command = reader.GetString() ?? "";
break;
case "path": item.Path = reader.GetString(); break;
case "parent": item.Parent = reader.GetString(); break;
case "type": item.Type = reader.GetString(); break;View on GitHub (pinned to 1ced45e900)
Solutions
- Make every batch element an item object with a command/op key.
- Validate each element is a non-null object before serializing.
- Map shorthand command strings to {command: <name>, ...} objects.
Example fix
// before: await doc.batch(['set', 'get']) // strings, not item objects
// after: await doc.batch([{ command:'set', path:'/A1', props:{text:'x'} }, { command:'get', path:'/A1' }]) Defensive patterns
Strategy: type-guard
Validate before calling
// Ensure every batch element is an item object before batching
function validBatch(items) {
return Array.isArray(items) && items.every(it => it && typeof it === 'object' && !Array.isArray(it) && typeof (it.command || it.op) === 'string');
} Type guard
function isBatchItem(it) {
return it !== null && typeof it === 'object' && !Array.isArray(it) && typeof (it.command || it.op) === 'string';
} Prevention
- Build batch lists from item objects only, never bare strings/numbers.
- Filter the list through isBatchItem() before sending.
- Map shorthand command strings to {command: name} objects.
When it happens
Trigger: A batch list containing a non-object element: ["set", {command:'set',...}] or [42] or [[...]]. Passing a flat array of command names instead of item objects.
Common situations: An agent/model emitting shorthand command strings instead of item objects; serializing a list of strings by mistake; a schema mismatch where the batch became an array of arrays.
Related errors
- Expected "key=value" string in props array
- Expected object or ["key=value"] array for props
- Unexpected token {reader.TokenType} for prop value '{key}'
- Expected PropertyName
- Unexpected end of JSON
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/abc67c867fa4fd4e.
Report an issue: GitHub.