iOfficeAI/OfficeCLI · error · ArgumentException

'remove' command requires 'path' field. Example: {"command":

Error message

'remove' command requires 'path' field. Example: {"command": "remove", "path": "/slide[1]/shape[2]"}

What it means

Thrown by the batch 'remove' command when item.Path is null or empty. The remove operation needs a concrete target element to delete, so an absent path is a hard error rather than a no-op. The message shows the expected JSON shape and is followed (if it passed) by MutationSelectorGuard.EnsureScoped which additionally forbids removing a whole-root path.

Source

Thrown at src/officecli/CommandBuilder.cs:1141

                    {
                        "tsv" => '\t',
                        "csv" => ',',
                        _ => throw new CliException($"Unknown format: {importFmt}. Use 'csv' or 'tsv'")
                            { Code = "invalid_value", ValidValues = ["csv", "tsv"] },
                    };
                }
                var importHeader = props.TryGetValue("header", out var importHdr)
                    && OfficeCli.Core.ParseHelpers.IsTruthy(importHdr);
                var importStart = props.TryGetValue("start-cell", out var importSc) && !string.IsNullOrEmpty(importSc)
                    ? importSc
                    : props.TryGetValue("startcell", out var importSc2) && !string.IsNullOrEmpty(importSc2)
                        ? importSc2 : "A1";
                return importXl.Import(importParent, item.Text, importDelim, importHeader, importStart);
            }
            case "remove":
            {
                if (string.IsNullOrEmpty(item.Path))
                    throw new ArgumentException("'remove' command requires 'path' field. Example: {\"command\": \"remove\", \"path\": \"/slide[1]/shape[2]\"}");
                var path = item.Path;
                OfficeCli.Core.MutationSelectorGuard.EnsureScoped(path, "remove");
                var warning = RemoveWithShiftSupport(handler, path, item.Props);
                var msg = $"Removed {path}";
                if (warning != null) msg += $"\n{warning}";
                return msg;
            }
            case "move":
            {
                var path = item.Path ?? "/";
                InsertPosition? movePos = null;
                if (item.Index.HasValue) movePos = InsertPosition.AtIndex(item.Index.Value);
                else if (!string.IsNullOrEmpty(item.After)) movePos = InsertPosition.AfterElement(item.After);
                else if (!string.IsNullOrEmpty(item.Before)) movePos = InsertPosition.BeforeElement(item.Before);
                // Pass props to the 4-arg Move like the CLI and resident do; the
                // batch/MCP path previously dropped move-time properties.
                var resultPath = handler.Move(path, item.To, movePos, props.Count > 0 ? props : null);
                return $"Moved to {resultPath}";

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Add a 'path' field pointing at the element to delete, e.g. /slide[1]/shape[2].
  2. Make sure the path is scoped (contains a [index]) — MutationSelectorGuard rejects bare root removal.
  3. If removing by selector, first run 'query' to resolve a concrete indexed path, then pass that path to 'remove'.

Example fix

// before
{"command":"remove"}
// after
{"command":"remove","path":"/slide[1]/shape[2]"}
Defensive patterns

Strategy: validation

Validate before calling

if (string.IsNullOrEmpty(item.Path))
    throw new ArgumentException("'remove' requires 'path' pointing at an indexed element, e.g. /slide[1]/shape[2]");
if (!item.Path.Contains('['))
    throw new ArgumentException("'remove' path must be scoped (contain an [index]); root removal is not allowed");

Type guard

static bool IsRemovablePath(string? p) =>
    !string.IsNullOrEmpty(p) && p.Contains('[') && p.Contains(']');

Try / catch

try { result = Dispatch(item); }
catch (ArgumentException ex) when (ex.Message.Contains("'remove' command requires 'path'"))
{ /* log, resolve a path via query, and retry */ }

Prevention

When it happens

Trigger: A batch item {"command":"remove"} with no 'path' field, or with 'path':''/'path':null. Also when a caller puts the target under a different key (e.g. 'parent' or 'to') expecting remove to accept it.

Common situations: An agent reuses an 'add' item template (which uses parent/type) and only flips the command to 'remove' without adding a 'path'. A query-first workflow that drops the path when zero or many nodes matched earlier.

Related errors


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