symfony/css-selector · error · SyntaxErrorException
String not allowed as function argument.
Error message
String not allowed as function argument.
What it means
Parser::parseSeries() parses the (an? b?) argument of :nth-child()/:nth-last-child() pseudo-classes. Before numeric parsing it rejects any Token of TYPE_STRING with SyntaxErrorException::stringAsFunctionArgument(), because quoted values are never valid inside these functional pseudo-classes.
Solutions
- Remove the quotes from the nth-child argument: :nth-child("2") becomes :nth-child(2).
- When building tokens programmatically, emit TYPE_NUMBER or TYPE_IDENTIFIER tokens instead of TYPE_STRING for the argument.
- Validate the argument shape (integer or 'odd'/'even'/'an+b') before passing to parseSeries().
Example fix
// before
$css = 'li:nth-child("2")'; // string token, throws
// after
$css = 'li:nth-child(2)'; // bare argument Defensive patterns
Strategy: validation
Validate before calling
// nth arguments must be bare, not quoted
if (!preg_match('/^:(?:nth-(?:last-)?(?:child|of-type))\(\s*(?:odd|even|-?\d+n?(?:\s*[+-]\s*\d+)?)\s*\)$/i', $pseudoSelector)) {
throw new \InvalidArgumentException('Invalid :nth-child argument (must be unquoted an+b / odd / even)');
} Try / catch
use Symfony\Component\CssSelector\Exception\SyntaxErrorException;
try {
[$a, $b] = Parser::parseSeries($tokens);
} catch (SyntaxErrorException $e) {
// reject selector or fall back to a simpler child selector
} Prevention
- Never quote :nth-child arguments; interpolate numbers directly
- Pre-validate an+b expressions with a regex before parsing
- When constructing tokens programmatically, use NUMBER/IDENTIFIER token types, never STRING
When it happens
Trigger: Calling parseSeries() (directly, as in testParseSeriesException, or via nth-child translation) with a token stream containing a string token — e.g. a selector like :nth-child("2") where the argument was tokenized as a string.
Common situations: Programmatic token construction that wrapped the nth argument in quotes; templates interpolating quoted values into :nth-child(); misunderstanding that nth arguments are plain numbers/identifiers, not strings.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Unclosed/invalid string at
- Unexpected pseudo-element
- Got immediate child pseudo-element
- Got too deeply nested
- Invalid series: " ".
AI-assisted analysis of symfony/css-selector@08e2905152 (2026-09-14).
Data as JSON: /api/errors/31858b3a7a4fa405.
Report an issue: GitHub.
Appendix: source
Thrown at Parser/Parser.php:62
{
$reader = new Reader($source);
$stream = $this->tokenizer->tokenize($reader);
return $this->parseSelectorList($stream);
}
/**
* Parses the arguments for ":nth-child()" and friends.
*
* @param Token[] $tokens
*
* @throws SyntaxErrorException
*/
public static function parseSeries(array $tokens): array
{
foreach ($tokens as $token) {
if ($token->isString()) {
throw SyntaxErrorException::stringAsFunctionArgument();
}
}
$joined = trim(implode('', array_map(static fn (Token $token) => $token->getValue(), $tokens)));
$int = static function ($string) {
if (!is_numeric($string)) {
throw SyntaxErrorException::stringAsFunctionArgument();
}
return (int) $string;
};
switch (true) {
case 'odd' === $joined:
return [2, 1];
case 'even' === $joined:
return [2, 0];View on GitHub (pinned to 08e2905152)