iOfficeAI/OfficeCLI · error · ArgumentException
batch item[{ni}] is null. Each entry must be a JSON object (
Error message
batch item[{ni}] is null. Each entry must be a JSON object (e.g. {"command":"get","path":"/"}). What it means
Thrown when a batch array contains an explicit null entry (e.g. `[null]` or `[{...}, null]`). System.Text.Json deserializes these into a List<BatchItem> with a null slot that would later trip a NullReferenceException inside ExecuteBatchItem; the up-front loop at line 323-328 rejects them with a recognizable, index-pointed ArgumentException (tagged BUG-R40-B11).
Source
Thrown at src/officecli/CommandBuilder.Batch.cs:326
if (unknown.Count > 0)
throw new ArgumentException($"batch item[{ri}]: unknown field(s) {string.Join(", ", unknown.Select(f => $"\"{f}\""))}. Valid fields: {string.Join(", ", BatchItem.KnownFields)}");
}
ri++;
}
}
var items = System.Text.Json.JsonSerializer.Deserialize<List<BatchItem>>(jsonText, BatchJsonContext.Default.ListBatchItem) ?? new();
// NEWLINE-SEMANTICS-V2: strip meta items; rewrite legacy (\n = soft
// break) docx dumps to the v2 encoding before execution.
OfficeCli.Core.BatchCompat.PrepareForReplay(items, file.FullName);
// BUG-R40-B11: explicit null entries (e.g. `[null]`) deserialize
// to a List<BatchItem> with a null slot and trip a NRE deeper in
// ExecuteBatchItem. Reject up-front with a recognizable error
// pointing at the offending index.
for (int ni = 0; ni < items.Count; ni++)
{
if (items[ni] == null)
throw new ArgumentException(
$"batch item[{ni}] is null. Each entry must be a JSON object (e.g. {{\"command\":\"get\",\"path\":\"/\"}}).");
}
if (items.Count == 0)
{
// BUG-R6-07: empty command array previously short-circuited
// before the file-existence check, so
// officecli batch /missing.docx --commands '[]' --json
// returned a clean zero-result success instead of the
// expected file_not_found. Validate the target file
// exists first so empty-array semantics match the
// non-empty path's diagnostics.
if (!file.Exists)
throw new CliException($"File not found: {file.FullName}")
{ Code = "file_not_found" };
// BUG-R7-09: in --json mode an empty/null batch input
// previously skipped the {"success":...,"data":{...}}
// envelope used by the populated-array path, so AI agents
// saw a missing `success` key. Apply the same envelopeView on GitHub (pinned to 1ced45e900)
Solutions
- Remove null entries from the batch array; every element must be a JSON object.
- Filter nulls before writing: `jq '[.[] | select(. != null)]' ops.json`.
- Ensure the producer never appends null on its error/fallback paths.
Example fix
// before
[{"command":"get"}, null]
// after
[{"command":"get"}] Defensive patterns
Strategy: validation
Validate before calling
// Strip null entries before deserializing/sending.
using var d = System.Text.Json.JsonDocument.Parse(jsonText);
if (d.RootElement.EnumerateArray().Any(e => e.ValueKind == System.Text.Json.JsonValueKind.Null))
throw new ArgumentException("batch array contains null entries"); Type guard
// Guard: no null slots.
static bool NoNullSlots(string json)
{
try
{
using var d = System.Text.Json.JsonDocument.Parse(json);
return !d.RootElement.EnumerateArray().Any(e => e.ValueKind == System.Text.Json.JsonValueKind.Null);
}
catch { return false; }
} Prevention
- Never append null on fallback branches when building the ops array programmatically.
- Filter with `jq '[.[] | select(. != null)]'` in pipelines.
When it happens
Trigger: `officecli batch file.docx --commands '[null]'` or `[{"command":"get"}, null]`. The deserialized list has a null slot caught by the ni-loop.
Common situations: An agent emits a trailing comma producing a null; a JSON template has an empty placeholder; programmatic array construction appends null on an error branch; JSON.stringify of an array with a null element.
Related errors
- Batch input must be a JSON array. Got: {rootKind.ToString().
- batch item[{ri}]: unknown field(s) {string.Join(", ", unknow
- Expected "key=value" string in props array
- Unexpected end of JSON
- Expected object or ["key=value"] array for props
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/1777928928121039.
Report an issue: GitHub.