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

  1. Add the missing ']' so every '[' in the selector has a matching ']'.
  2. Count/validate bracket balance (respecting quoted strings) before calling toXPath().
  3. Quote values that contain '[' or ']' characters so they tokenize as strings.
  4. 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

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


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)