iOfficeAI/OfficeCLI · error · ArgumentException
'add' command requires 'type' or 'from' field. Example: {"co
Error message
'add' command requires 'type' or 'from' field. Example: {"command": "add", "parent": "/", "type": "slide"} What it means
Thrown by ExecuteBatchItem for a batch "add" step that has a parent but neither "type" (what kind of element to create) nor "from" (a source path to copy via handler.CopyFrom). At least one of the two is required.
Source
Thrown at src/officecli/CommandBuilder.cs:1057
// requested property was rejected (nothing applied), the
// step is a failure, not a successful no-op. Without
// this, batch swallowed unsupported_property into an inner
// success=true while the same set issued via the
// standalone set command returned success=false exit 2.
// Per-step verdict flips to false; outer batch envelope
// still rides on the existing partial-success rule.
if (applied.Count == 0)
throw new CliException(string.Join("\n", parts)) { Code = "unsupported_property" };
}
return string.Join("\n", parts);
}
case "add":
{
var parentPath = item.Parent ?? item.Path;
if (string.IsNullOrEmpty(parentPath))
throw new ArgumentException("'add' command requires 'parent' field. Example: {\"command\": \"add\", \"parent\": \"/slide[1]\", \"type\": \"shape\", \"props\": {\"text\": \"Hello\"}}");
if (string.IsNullOrEmpty(item.Type) && string.IsNullOrEmpty(item.From))
throw new ArgumentException("'add' command requires 'type' or 'from' field. Example: {\"command\": \"add\", \"parent\": \"/\", \"type\": \"slide\"}");
InsertPosition? pos = null;
if (item.Index.HasValue) pos = InsertPosition.AtIndex(item.Index.Value);
else if (!string.IsNullOrEmpty(item.After)) pos = InsertPosition.AfterElement(item.After);
else if (!string.IsNullOrEmpty(item.Before)) pos = InsertPosition.BeforeElement(item.Before);
if (!string.IsNullOrEmpty(item.From))
{
var resultPath = handler.CopyFrom(item.From, parentPath, pos);
return $"Copied to {resultPath}";
}
else
{
var type = item.Type ?? "";
// Wrap props in a tracking dict (matches CLI/resident add): a
// key the handler reads is consumed, so UnusedKeys after Add
// is the generic unsupported-prop set across ALL handlers.
// Previously batch/MCP add saw only Word's curated
// LastAddUnsupportedProps, silently dropping an unknown propView on GitHub (pinned to 1ced45e900)
Solutions
- Add a type: {"command":"add","parent":"/","type":"slide"}.
- Or add a from to copy an existing element: {"command":"add","parent":"/","from":"/slide[1]"}.
- Validate every add step has a non-empty type or from before submission.
- Ensure type is not an empty string (empty string fails the IsNullOrEmpty check).
Example fix
// before
{"command":"add","parent":"/","type":""}
// after
{"command":"add","parent":"/","type":"slide"} Defensive patterns
Strategy: validation
Validate before calling
if (string.IsNullOrEmpty(item.Type) && string.IsNullOrEmpty(item.From))
throw new ArgumentException("'add' requires a non-empty 'type' or 'from'"); Type guard
static bool IsValidAddItem(BatchItem i)
=> !string.IsNullOrEmpty(i.Parent ?? i.Path)
&& (!string.IsNullOrEmpty(i.Type) || !string.IsNullOrEmpty(i.From)); Prevention
- Ensure type is non-empty (empty string fails the guard too).
- Use 'from' when copying an existing element instead of 'type'.
- Validate add items against the schema before submission.
When it happens
Trigger: {"command":"add","parent":"/slide[1]"}; an add step where a conditional left both type and from null; type emitted as an empty string.
Common situations: Forgotten type field; conditional logic that failed to set a type; a generator that emitted parent but not type; confusion between create (type) and copy (from).
Related errors
- 'add' command requires 'parent' field. Example: {"command":
- invalid_input
- Path not found: {path}
- 'query' command requires 'selector' field. Example: {"comman
- 'set' command requires 'path' field. Example: {"command": "s
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/8d69d71184ab776d.
Report an issue: GitHub.