symfony/css-selector · error · ExpressionErrorException

Attribute matcher operator

Error message

Attribute matcher operator "%s" not supported.

What it means

Translator::addAttributeMatching() dispatches an attribute matcher operator (=, ^=, $=, *=, ~=, |=) to a handler in $this->attributeMatchingTranslators and throws ExpressionErrorException when the operator is unknown. The operator normally comes from parsed Attribute nodes, so valid CSS never triggers this — it is a guard for the extension/programmatic API.

Solutions

  1. Use a standard CSS attribute operator: =, ^=, $=, *=, ~=, |=.
  2. Register a custom attribute matching translator via Translator::extension() for non-standard operators.
  3. Verify the operator value produced by the parser for the attribute selector in question.

Example fix

// before
$translator->addAttributeMatching($xpath, '!==', 'href', 'x'); // unknown operator, throws

// after
$translator->addAttributeMatching($xpath, '!=', 'href', 'x'); // only if registered, else use '=' and filter
// safest: use a supported operator
$translator->addAttributeMatching($xpath, '=', 'href', 'x');
Defensive patterns

Strategy: validation

Validate before calling

const VALID_ATTR_OPS = ['=', '^=', '$=', '*=', '~=', '!=', '|='];
if (!in_array($operator, self::VALID_ATTR_OPS, true)) {
    throw new \InvalidArgumentException("Invalid attribute operator: $operator");
}

Try / catch

use Symfony\Component\CssSelector\Exception\ExpressionErrorException;
try {
    $expr = $translator->addAttributeMatching($xpath, $op, $attr, $value);
} catch (ExpressionErrorException $e) {
    // coerce to '=' or skip the attribute condition
}

Prevention

When it happens

Trigger: Calling addAttributeMatching() with an $operator string not among the registered matchers (e.g. '!==' or an empty string), typically from custom node construction or a test such as testAddAttributeMatchingClassNotExistsClass.

Common situations: Programmatic XPathExpr/Attribute node building with an invalid operator; custom selector dialects with new operators lacking a registered matcher; corrupted tokenization upstream.

Related errors


AI-assisted analysis of symfony/css-selector@08e2905152 (2026-09-14). Data as JSON: /api/errors/56298f64e6d2b31d. Report an issue: GitHub.

Appendix: source

Thrown at XPath/Translator.php:217

    /**
     * @throws ExpressionErrorException
     */
    public function addPseudoClass(XPathExpr $xpath, string $pseudoClass): XPathExpr
    {
        if (!isset($this->pseudoClassTranslators[$pseudoClass])) {
            throw new ExpressionErrorException(\sprintf('Pseudo-class "%s" not supported.', $pseudoClass));
        }

        return $this->pseudoClassTranslators[$pseudoClass]($xpath);
    }

    /**
     * @throws ExpressionErrorException
     */
    public function addAttributeMatching(XPathExpr $xpath, string $operator, string $attribute, ?string $value): XPathExpr
    {
        if (!isset($this->attributeMatchingTranslators[$operator])) {
            throw new ExpressionErrorException(\sprintf('Attribute matcher operator "%s" not supported.', $operator));
        }

        return $this->attributeMatchingTranslators[$operator]($xpath, $attribute, $value);
    }

    /**
     * @return SelectorNode[]
     */
    private function parseSelectors(string $css): array
    {
        foreach ($this->shortcutParsers as $shortcut) {
            $tokens = $shortcut->parse($css);

            if ($tokens) {
                return $tokens;
            }
        }

View on GitHub (pinned to 08e2905152)