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 prop

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Add a type: {"command":"add","parent":"/","type":"slide"}.
  2. Or add a from to copy an existing element: {"command":"add","parent":"/","from":"/slide[1]"}.
  3. Validate every add step has a non-empty type or from before submission.
  4. 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

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


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