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

  1. Remove the quotes from the nth-child argument: :nth-child("2") becomes :nth-child(2).
  2. When building tokens programmatically, emit TYPE_NUMBER or TYPE_IDENTIFIER tokens instead of TYPE_STRING for the argument.
  3. 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

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


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)