iOfficeAI/OfficeCLI · error · CliException
invalid_selector
invalid_selector
Error message
Malformed selector: unclosed bracket in "{selector}" What it means
Thrown by AttributeFilter.Parse when the number of '[' characters in the selector does not equal the number of ']' characters. Attribute filters live inside brackets ([key=value], [key]), so an unbalanced bracket cannot form a valid filter. This is the simple (flat) parser used for single-condition selectors. It is a CliException with Code=invalid_selector.
Source
Thrown at src/officecli/Core/AttributeFilter.cs:105
return blocks;
}
// Regex: numeric positional index [N] only (used for reverse-doc-order keys).
private static readonly Regex BracketIndexRegex = new(
@"\[(\d+)\]",
RegexOptions.Compiled);
/// <summary>
/// Parse all [key op value] conditions from a selector string.
/// Throws CliException for malformed selectors.
/// </summary>
public static List<Condition> Parse(string selector)
{
// Check for unclosed brackets
var openCount = selector.Count(c => c == '[');
var closeCount = selector.Count(c => c == ']');
if (openCount != closeCount)
throw new CliException($"Malformed selector: unclosed bracket in \"{selector}\"")
{
Code = "invalid_selector",
Suggestion = "Ensure every '[' has a matching ']'. Example: paragraph[style=Heading 1]"
};
var conditions = new List<Condition>();
var matchedSpans = new HashSet<(int Start, int End)>();
foreach (Match m in AttrRegex.Matches(selector))
{
var key = m.Groups[1].Value;
var opStr = m.Groups[2].Value.Replace("\\", "");
var rawVal = m.Groups[3].Value;
// CONSISTENCY(find-regex): preserve quotes when the value is the
// `r"..."` / `r'...'` regex form so MatchOne can detect it. Trim
// would otherwise eat the surrounding quote that marks the prefix.
var isRegexForm = rawVal.Length >= 3 && rawVal[0] == 'r'
&& (rawVal[1] == '"' || rawVal[1] == '\'');View on GitHub (pinned to 1ced45e900)
Solutions
- Count brackets and add the missing ']' so every '[' has a matching ']'.
- If a value contains a literal bracket, wrap it in quotes ("...") or use the r"..." regex form so the quote-aware parser treats it as text.
- Prefer the boolean-expression syntax (e.g. cell[a and b]) which is bracket-aware.
Example fix
# before query 'shape[fill=#FF0000' # after query 'shape[fill=#FF0000]'
Defensive patterns
Strategy: validation
Validate before calling
static void EnsureBalancedBrackets(string selector)
{
var open = selector.Count(c => c == '[');
var close = selector.Count(c => c == ']');
if (open != close)
throw new ArgumentException($"Selector has {open} '[' and {close} ']'; they must balance.");
} Type guard
static bool HasBalancedBrackets(string s) =>
s.Count(c => c == '[') == s.Count(c => c == ']'); Try / catch
try { conditions = AttributeFilter.Parse(selector); }
catch (CliException ex) when (ex.Code == "invalid_selector" && ex.Message.Contains("unclosed bracket"))
{ /* balance the selector and retry */ } Prevention
- Always pair every '[' with a ']' when editing selectors.
- If a value contains a bracket, quote it so the quote-aware parser treats it literally.
- Validate bracket balance before sending a selector to the API.
When it happens
Trigger: A selector like 'shape[fill=#FF0000' (missing closing bracket), or 'shape[fill=#FF0000][size' (second bracket unclosed). A path copied from output where a trailing ']' was trimmed.
Common situations: A user edits a working selector and deletes a ']'. An agent truncates a long path string. A value containing a literal ']' that the simple counter misreads (use the boolean-expression parser / quote the value instead).
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- invalid_selector
- Invalid --prop '{prop}': key is empty. Use key=value (e.g. -
- invalid_argument
- bare_selector_rejected
- invalid_selector
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/45d2b503f8dc333e.
Report an issue: GitHub.