symfony/css-selector · error · SyntaxErrorException
]
Error message
]
What it means
This SyntaxErrorException is thrown at the end of an attribute selector: after the operator and value, the parser requires the closing ']' delimiter and found another token instead. The attribute selector was never properly terminated.
Solutions
- Add the missing ']' so every '[' in the selector has a matching ']'.
- Count/validate bracket balance (respecting quoted strings) before calling toXPath().
- Quote values that contain '[' or ']' characters so they tokenize as strings.
- Check for truncation if the selector comes from an external source or was sliced in code.
Example fix
// before
$xpath = $converter->toXPath('a[href="example.com"');
// after
$xpath = $converter->toXPath('a[href="example.com"]'); Defensive patterns
Strategy: validation
Validate before calling
// check bracket balance ignoring quoted strings before conversion
function bracketsBalanced(string $s): bool {
$depth = 0; $inStr = false; $q = '';
for ($i = 0, $n = strlen($s); $i < $n; $i++) {
$c = $s[$i];
if ($inStr) { if ($c === $q) $inStr = false; continue; }
if ($c === '"' || $c === "'") { $inStr = true; $q = $c; continue; }
if ($c === '[') $depth++;
if ($c === ']') { $depth--; if ($depth < 0) return false; }
}
return $depth === 0;
} Type guard
function attributeSelectorsClosed(string $s): bool {
return substr_count($s, '[') === substr_count($s, ']');
} Try / catch
try {
$xpath = $converter->toXPath($selector);
} catch (\Symfony\Component\CssSelector\Exception\SyntaxErrorException $e) {
if (!bracketsBalanced($selector)) {
throw new InvalidArgumentException('Unbalanced [ ] in attribute selector.');
}
throw $e;
} Prevention
- Quote values containing '[' or ']' so they tokenize as strings.
- Check bracket balance (string-aware) on any generated selector.
- Watch for template engines or string slicing that can drop the final ']'.
When it happens
Trigger: Selectors like 'a[href="x")', 'input[type="text" >', '[data-x="v" and [data-y]', or a missing ']' caused by an unclosed earlier '[' so the brackets are unbalanced by the time the value is parsed.
Common situations: Unbalanced brackets from dynamically assembled selectors; copy-paste truncation cutting off the final ']'; nesting confusion like '[a="[x]"]' where quotes around brackets are omitted; templating engines stripping the bracket.
Related errors
- Unexpected pseudo-element
- Got immediate child pseudo-element
- string or identifier
- identifier
- identifier or "*"
AI-assisted analysis of symfony/css-selector@08e2905152 (2026-09-14).
Data as JSON: /api/errors/efc8b83b0b915456.
Report an issue: GitHub.
Appendix: source
Thrown at Parser/Parser.php:472
}
$stream->skipWhitespace();
$value = $stream->getNext();
if ($value->isNumber()) {
// if the value is a number, it's casted into a string
$value = new Token(Token::TYPE_STRING, (string) $value->getValue(), $value->getPosition());
}
if (!($value->isIdentifier() || $value->isString())) {
throw SyntaxErrorException::unexpectedToken('string or identifier', $value);
}
$stream->skipWhitespace();
$next = $stream->getNext();
if (!$next->isDelimiter([']'])) {
throw SyntaxErrorException::unexpectedToken('"]"', $next);
}
return new Node\AttributeNode($selector, $namespace, $attribute, $operator, $value->getValue());
}
}
View on GitHub (pinned to 08e2905152)