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

  1. Add a parent: {"command":"add","parent":"/","type":"slide"}.
  2. Provide "path" as the fallback if parent is unset.
  3. Validate every add step has a non-empty parent (or path) before submission.
  4. 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

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


AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13). Data as JSON: /api/errors/4a3f0f3c33d76699. Report an issue: GitHub.