iOfficeAI/OfficeCLI · error · Core.CliException
invalid_selector
invalid_selector
Error message
'{selector}' is not a valid selector: a predicate must be inside brackets, e.g. row[col.2024>150] to filter table rows by a column, or cell[value>150] to filter cells. What it means
Thrown (code invalid_selector) when a query selector contains a comparison operator (>, <, =, etc.) OUTSIDE any bracket, e.g. 'col.2024>150' or 'Dept=IT' written bare. HasTopLevelComparison detects this; without the guard the selector would match no element type and silently return an empty list with exit 0 — a 'no rows' result a user mistakes for real data. The handler fails loud and shows the correct bracketed form.
Source
Thrown at src/officecli/Handlers/Excel/ExcelHandler.Query.cs:1136
// other Query branches. Single-cell refs return a one-element list.
var nativeCellRef = Regex.Match(selector, @"^([^/!]+)!([A-Z]+\d+(:[A-Z]+\d+)?)$", RegexOptions.IgnoreCase);
if (nativeCellRef.Success)
{
// 'My Data (2024)'!A1 — Excel requires quoting names with spaces;
// strip the quotes so the DOM path resolves the real sheet.
var node = Get($"/{UnquoteSheetName(nativeCellRef.Groups[1].Value)}/{nativeCellRef.Groups[2].Value}");
if (node.Type == "range" && node.Children.Count > 0)
return node.Children;
return [node];
}
// A comparison operator OUTSIDE any bracket means the predicate was
// written without its brackets (`col.2024>150`, `foo>1`, `Dept=IT`).
// Such a selector matches no element type and would otherwise return an
// empty list with exit 0 — a silent "no rows" that a data user reads as a
// real result. Fail loud with the bracketed form instead.
if (HasTopLevelComparison(selector))
throw new Core.CliException(
$"'{selector}' is not a valid selector: a predicate must be inside brackets, " +
$"e.g. row[col.2024>150] to filter table rows by a column, or cell[value>150] to filter cells.")
{ Code = "invalid_selector" };
// CONSISTENCY(excel-sheet-separator-warn): Detect the PPT-style `>`
// separator form (e.g. `Sheet1>ole`) that users familiar with the
// PowerPoint query grammar may try against Excel. Excel uses `!`
// (Sheet1!cell[...]) — the legacy spreadsheet separator — so a `>`
// in the sheet-prefix slot will silently fall through to generic
// XML and return an empty result. We emit a single stderr warning
// pointing to the correct `!` form, then let the normal flow run.
// Only fire when the prefix looks like a sheet name (no `/`) and
// the suffix is a known Excel element type we would have handled.
{
var pptStyle = Regex.Match(selector, @"^([^/!>]+)>(\w+)");
if (pptStyle.Success)
{
var suffixType = pptStyle.Groups[2].Value.ToLowerInvariant();View on GitHub (pinned to 1ced45e900)
Solutions
- Wrap the predicate in square brackets: row[col.2024>150] to filter table rows, or cell[value>150] to filter cells.
- When constructing selectors programmatically, always template the bracket form: f"row[col.{col}{op}{val}]".
- If you meant a path, not a filter, remove the comparison operator entirely.
Example fix
// before get row col.2024>150 // after get row[col.2024>150]
Defensive patterns
Strategy: validation
Validate before calling
import re
def brackets_present_around_predicate(selector):
# a comparison operator must sit inside [...]
outside = re.sub(r'\[[^\]]*\]', '', selector) # strip bracketed groups
return not re.search(r'[<>!=]=|[<>]', outside)
selector = 'col.2024>150'
assert brackets_present_around_predicate(selector), \
'predicate must be inside brackets, e.g. row[col.2024>150]' Type guard
null
Try / catch
null
Prevention
- Always wrap predicates in square brackets: row[col.x>150].
- When templating selectors, include the brackets in the template, not the value.
- Strip bracketed groups and re-scan for stray operators as a pre-check.
When it happens
Trigger: Query/remove with a predicate whose brackets were omitted: 'row col.2024>150' or a selector string like 'col.2024>150' instead of 'row[col.2024>150]'. Any top-level comparison operator triggers it.
Common situations: Forgetting the square brackets around a filter expression; building selectors by string concatenation that drops the brackets; migrating from a grammar that used parens or no delimiters.
Related errors
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/961e1e83645335ba.
Report an issue: GitHub.