iOfficeAI/OfficeCLI · error · ArgumentException
'add' command requires 'type' or 'from' field. Example
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.
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
- 'import' command requires 'parent' field (sheet path)…
- 'import' command requires 'text' field with the CSV/TSV…
- invalid_input
- Path not found
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/8d69d71184ab776d.
Report an issue: GitHub.
Appendix: 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)