iOfficeAI/OfficeCLI · error · ArgumentException
send: empty item
Error message
send: empty item
What it means
ExecuteSend deserializes a single batch-item JSON string into a BatchItem object. If deserialization returns null (the JSON was empty, whitespace-only, or a JSON null literal), the coalescing ?? operator throws ArgumentException. This mirrors the SDK send(item) contract: a null/empty item is a caller bug, not a batch-level failure. Unlike ExecuteBatch, the failure throws (not captured per-item) to match the standalone command's exit contract.
Source
Thrown at src/officecli/Core/BatchExecutor.cs:86
/// <summary>
/// Mirrors the SDKs' <c>send(item)</c> (as distinct from <c>batch(items)</c>):
/// runs ONE batch-shaped item and returns EXACTLY what the CLI single command
/// writes to stdout — with <paramref name="json"/> the standalone command's
/// envelope (WrapEnvelopeText's `{success,data,message}` for text commands
/// like set/add/remove, WrapEnvelope's `{success,data}` for data commands like
/// get/query), without it the plain text. A failure throws instead of being
/// captured per-item, matching the standalone command's exit contract.
/// </summary>
/// <param name="itemJson">A single batch item object — the same shape as one
/// entry in <see cref="ExecuteBatch"/>'s array, or the SDKs' `send(item)` argument.</param>
/// <param name="json">Mirrors the CLI `--json` toggle: structured envelope vs plain text.</param>
public static string ExecuteSend(IDocumentHandler handler, string itemJson, bool json)
{
try
{
var item = JsonSerializer.Deserialize(itemJson, BatchJsonContext.Default.BatchItem)
?? throw new ArgumentException("send: empty item");
var inner = CommandBuilder.ExecuteBatchItem(handler, item, json);
if (!json) return inner;
// Match the standalone command's envelope by inner shape — a JSON payload
// (get/query/view/validate/…) wraps with WrapEnvelope; a plain-text
// message (set/add/remove/…) wraps with WrapEnvelopeText (which adds the
// `message` field the CLI emits). Content-based so a new command inherits
// the right envelope without a hand-kept command→envelope map.
var trimmed = inner.TrimStart();
return trimmed.StartsWith('{') || trimmed.StartsWith('[')
? OutputFormatter.WrapEnvelope(inner)
: OutputFormatter.WrapEnvelopeText(inner);
}
catch (Exception ex)
{
return RenderTopLevelError(ex, json);
}
}View on GitHub (pinned to 1ced45e900)
Solutions
- Ensure itemJson is a valid BatchItem JSON object before calling ExecuteSend — check for null/empty/whitespace.
- Guard at the caller boundary: if (string.IsNullOrWhiteSpace(itemJson)) throw with a descriptive message.
- Verify the JSON is not the literal "null" — JsonSerialializer.Deserialize returns null for JSON null.
Example fix
// before
var result = BatchExecutor.ExecuteSend(handler, itemJson, json);
// after
if (string.IsNullOrWhiteSpace(itemJson) || itemJson.Trim() == "null")
throw new ArgumentException("itemJson must be a non-empty batch item JSON object.");
var result = BatchExecutor.ExecuteSend(handler, itemJson, json); Defensive patterns
Strategy: validation
Validate before calling
static void ValidateItemJson(string itemJson)
{
if (string.IsNullOrWhiteSpace(itemJson))
throw new ArgumentException("itemJson must be a non-empty JSON object.");
var trimmed = itemJson.Trim();
if (trimmed == "null")
throw new ArgumentException("itemJson is JSON null — provide a batch item object.");
}
// Usage:
ValidateItemJson(itemJson);
var result = BatchExecutor.ExecuteSend(handler, itemJson, json); Try / catch
try { var result = BatchExecutor.ExecuteSend(handler, itemJson, json); }
catch (ArgumentException ex) when (ex.Message == "send: empty item")
{
// The caller passed null/empty/whitespace/"null" JSON
throw new ArgumentException("Batch item was empty. Provide a valid JSON item object.", ex);
} Prevention
- Always check string.IsNullOrWhiteSpace before calling ExecuteSend.
- Guard against the JSON literal "null" which deserializes to null.
- In SDK wrappers, validate user-supplied input before forwarding to ExecuteSend.
When it happens
Trigger: Calling BatchExecutor.ExecuteSend with an empty string, "null", whitespace, or a JSON literal that deserializes to null. Common in SDK send(item) wrappers that forward user-supplied input without checking for emptiness.
Common situations: An SDK wrapper passes a default/empty string when the user provides no item. A serialization bug produces 'null' or '' instead of a valid item JSON. A network layer sends an empty body after stripping content.
Related errors
- Expected "key=value" string in props array
- Unexpected end of JSON
- Expected object or ["key=value"] array for props
- Expected property name
- Unexpected token {reader.TokenType} for prop value '{key}'
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/0d18d1699e8a8336.
Report an issue: GitHub.