iOfficeAI/OfficeCLI · error · ArgumentException
'add' command requires 'parent' field. Example: {"command":
Error message
'add' command requires 'parent' field. Example: {"command": "add", "parent": "/slide[1]", "type": "shape", "props": {"text": "Hello"}} What it means
Thrown by ExecuteBatchItem for a batch "add" step when both "parent" and "path" are null/empty (path is used as a fallback for parent). Add needs a parent container to insert into; there is no implicit root. The example in the message shows the expected shape.
Source
Thrown at src/officecli/CommandBuilder.cs:1055
}
// Mirror standalone `set`'s allFailed semantics: if every
// 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.View on GitHub (pinned to 1ced45e900)
Solutions
- Add a parent: {"command":"add","parent":"/","type":"slide"}.
- Provide "path" as the fallback if parent is unset.
- Validate every add step has a non-empty parent (or path) before submission.
- For top-level adds (e.g. a new slide), use parent "/".
Example fix
// before
{"command":"add","type":"slide"}
// after
{"command":"add","parent":"/","type":"slide"} Defensive patterns
Strategy: validation
Validate before calling
var parent = item.Parent ?? item.Path;
if (string.IsNullOrEmpty(parent))
throw new ArgumentException("'add' requires a non-empty 'parent' (or 'path')"); Type guard
static bool IsValidAddItem(BatchItem i)
=> !string.IsNullOrEmpty(i.Parent ?? i.Path)
&& (!string.IsNullOrEmpty(i.Type) || !string.IsNullOrEmpty(i.From)); Prevention
- Always set parent (or path) on add steps; use "/" for top-level.
- Validate add items against the schema before submission.
- Guard against null/empty parent variables.
When it happens
Trigger: {"command":"add","type":"slide"} (no parent); an add step whose parent/path variables were both empty; a templating bug that dropped the parent field.
Common situations: Forgotten parent field in a hand-written batch; a parent computed from a null/empty variable; a generator that emitted type but not parent; copy-paste that lost the parent line.
Related errors
- 'add' command requires 'type' or 'from' field. Example: {"co
- 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/4a3f0f3c33d76699.
Report an issue: GitHub.