symfony/css-selector · error · SyntaxErrorException
string or identifier
Error message
string or identifier
What it means
This SyntaxErrorException is thrown when the value of an attribute selector comparison is neither an identifier nor a string (numbers are auto-cast to strings, but anything else fails). The parser reports 'Expected string or identifier, but X found.'
Solutions
- Quote the attribute value: '[data-x="value"]' instead of relying on a raw token in the value position.
- Ensure the interpolated value is a scalar and cast it: sprintf('[data-x="%s"]', (string) $value).
- Escape embedded quotes, or use single quotes for the CSS string when the value contains double quotes.
- Remove duplicated '=' from the operator before the value.
Example fix
// before
$xpath = $converter->toXPath(sprintf('div[data-id=%s]', $id)); // $id = ['a'] -> invalid token
// after
$xpath = $converter->toXPath(sprintf('div[data-id="%s"]', (string) $id)); Defensive patterns
Strategy: validation
Validate before calling
// always quote and escape the value when building attribute selectors
function attrSelector(string $attr, string $op, string $value): string {
return sprintf('[%s%s"%s"]', $attr, $op, str_replace('"', '\\"', $value));
} Type guard
function isQuotableScalar($v): bool {
return is_scalar($v);
} Prevention
- Always wrap attribute values in quotes when interpolating variables.
- Cast values to string and escape embedded quotes before insertion.
- Avoid double operators ('==') which push a stray '=' into the value position.
When it happens
Trigger: Selectors like 'a[href="x"' where a stray token appears in the value position: 'div[data-x="a"b]', '[data-x=="v"]', an unquoted value containing invalid characters, or a value built by interpolating non-scalar data (array/null) into the selector string.
Common situations: Interpolating PHP variables that json_encode/array-cast oddly into the selector; double quotes inside single-quoted strings or vice versa breaking tokenization; operators accidentally duplicated so the second '=' lands in the value slot.
Related errors
- ]
- Attribute matcher operator
- Unexpected pseudo-element
- Got too deeply nested :has().
- Expected , but found.
AI-assisted analysis of symfony/css-selector@08e2905152 (2026-09-14).
Data as JSON: /api/errors/992dca9ada63bc07.
Report an issue: GitHub.
Appendix: source
Thrown at Parser/Parser.php:465
&& $stream->getPeek()->isDelimiter(['='])
) {
$operator = $next->getValue().'=';
$stream->getNext();
} else {
throw SyntaxErrorException::unexpectedToken('operator', $next);
}
}
$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)