iOfficeAI/OfficeCLI · error · ArgumentException

'query' command requires 'selector' field. Example: {"comman

Error message

'query' command requires 'selector' field. Example: {"command": "query", "selector": "row[Score>80]"}

What it means

Thrown by ExecuteBatchItem for a batch "query" step when both "selector" and "path" are null/empty. An empty selector would silently match every node (the most dangerous wrong-data outcome), so it is rejected. "path" is accepted as an alias for "selector" to mirror the CLI, so setting either satisfies the requirement.

Source

Thrown at src/officecli/CommandBuilder.cs:966

                    throw new ArgumentException(node.Text ?? $"Path not found: {path}");
                // Unified envelope: batch get items emit the same
                // {matches, results: [...]} shape as query items, so callers
                // can consume batch step output with a single parser.
                if (format == OutputFormat.Json)
                    return OfficeCli.Core.OutputFormatter.FormatNodes(new List<DocumentNode> { node }, format);
                return OfficeCli.Core.OutputFormatter.FormatNode(node, format);
            }
            case "query":
            {
                // `path` is accepted as an alias for `selector` — the generic
                // field table says "path (set/remove/get target)" and users
                // carry it over to query; ignoring it silently ran an EMPTY
                // selector, i.e. returned every node as if the predicate
                // matched (the most dangerous kind of wrong data). Neither
                // field present is an error, mirroring the required CLI arg.
                var selector = item.Selector ?? item.Path ?? "";
                if (string.IsNullOrEmpty(selector))
                    throw new ArgumentException("'query' command requires 'selector' field. Example: {\"command\": \"query\", \"selector\": \"row[Score>80]\"}");
                Func<string, string>? keyResolver =
                    handler is OfficeCli.Handlers.ExcelHandler
                    && OfficeCli.Handlers.ExcelHandler.SelectorTargetsCells(selector)
                        ? OfficeCli.Handlers.ExcelHandler.ResolveCellAttributeAlias : null;
                var (results, warnings) = OfficeCli.Core.AttributeFilter.FilterSelector(selector, handler.Query, keyResolver);
                if (item.Text is { } textFilter && !string.IsNullOrEmpty(textFilter))
                    // MatchesTextFilter (not plain Contains) so a batch query
                    // text filter honours r"regex" like the CLI and resident do.
                    results = results.Where(n => n.Text != null && OfficeCli.Core.AttributeFilter.MatchesTextFilter(n.Text, textFilter)).ToList();
                foreach (var w in warnings) Console.Error.WriteLine(w.Message);
                return OfficeCli.Core.OutputFormatter.FormatNodes(results, format);
            }
            case "set":
            {
                if (string.IsNullOrEmpty(item.Path))
                    throw new ArgumentException("'set' command requires 'path' field. Example: {\"command\": \"set\", \"path\": \"/slide[1]\", \"props\": {\"bold\": \"true\"}}");
                // Match standalone `set` rejection of empty/missing props — a
                // batch step with no props is a no-op that previously reported

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Add a selector: {"command":"query","selector":"row[Score>80]"}.
  2. If you intended to target a path, set "path" instead (it is accepted as an alias).
  3. Validate every query step has a non-empty selector/path before submitting the batch.
  4. Check for misspelled field names against the documented schema.

Example fix

// before
{"command":"query"}
// after
{"command":"query","selector":"row[Score>80]"}
Defensive patterns

Strategy: validation

Validate before calling

var selector = item.Selector ?? item.Path;
if (string.IsNullOrEmpty(selector))
    throw new ArgumentException("'query' requires a non-empty 'selector' (or 'path')");

Type guard

static bool IsValidQueryItem(BatchItem i)
    => !string.IsNullOrEmpty(i.Selector) || !string.IsNullOrEmpty(i.Path);

Prevention

When it happens

Trigger: {"command":"query"} with no fields; {"command":"query","selector":""}; a query step whose selector field was misspelled (e.g. "selectr").

Common situations: A template that omits the selector; a field misspelling; an AI/LLM-generated batch that dropped the field; a dynamic selector variable that evaluated to empty.

Related errors


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