symfony/css-selector · error · ExpressionErrorException

Combiner " " not supported.

Error message

Combiner "%s" not supported.

What it means

Translator::addCombination() looks up a combiner (' ', '>', '+', '~') in $this->combinationTranslators and throws ExpressionErrorException when the combiner string is not registered. The public translator maps cover all CSS combinators, so this surfaces almost exclusively when tests or extensions inject an unknown combiner key.

Solutions

  1. Use only standard CSS combinators: descendant (' '), child ('>'), adjacent sibling ('+'), general sibling ('~').
  2. Register a custom combination translator via an extension added with Translator::extension() before calling addCombination().
  3. Check the exact $combiner string for typos or stray whitespace.

Example fix

// before
$translator->addCombination('>>', $a, $b); // unknown combiner, throws

// after
$translator->addCombination('>', $a, $b); // standard child combinator
Defensive patterns

Strategy: validation

Validate before calling

const VALID_COMBINERS = [' ', '>', '+', '~'];
if (!in_array($combiner, self::VALID_COMBINERS, true)) {
    throw new \InvalidArgumentException("Invalid combiner: $combiner");
}

Try / catch

use Symfony\Component\CssSelector\Exception\ExpressionErrorException;
try {
    $result = $translator->addCombination($combiner, $a, $b);
} catch (ExpressionErrorException $e) {
    // fall back to descendant combination ' '
}

Prevention

When it happens

Trigger: Calling addCombination() with a $combiner string not present in combinationTranslators — e.g. a custom combiner symbol, a typo, or an empty string. As seen in testAddCombinationNotExistsExtension, the documented trigger is invoking the method before/without the matching extension being registered.

Common situations: Custom selector extensions defining new combination operators without registering a combination translator; typos when building combined selectors programmatically; test code exercising the error path with fake combiner values.

Related errors


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

Appendix: source

Thrown at XPath/Translator.php:169

    /**
     * @throws ExpressionErrorException
     */
    public function nodeToXPath(NodeInterface $node): XPathExpr
    {
        if (!isset($this->nodeTranslators[$node->getNodeName()])) {
            throw new ExpressionErrorException(\sprintf('Node "%s" not supported.', $node->getNodeName()));
        }

        return $this->nodeTranslators[$node->getNodeName()]($node, $this);
    }

    /**
     * @throws ExpressionErrorException
     */
    public function addCombination(string $combiner, NodeInterface $xpath, NodeInterface $combinedXpath): XPathExpr
    {
        if (!isset($this->combinationTranslators[$combiner])) {
            throw new ExpressionErrorException(\sprintf('Combiner "%s" not supported.', $combiner));
        }

        return $this->combinationTranslators[$combiner]($this->nodeToXPath($xpath), $this->nodeToXPath($combinedXpath));
    }

    /**
     * @throws ExpressionErrorException
     */
    public function addRelativeCombination(string $combiner, NodeInterface $xpath, NodeInterface $combinedXpath): XPathExpr
    {
        if (!isset($this->relativeCombinationTranslators[$combiner])) {
            throw new ExpressionErrorException(\sprintf('Combiner "%s" not supported.', $combiner));
        }

        return $this->relativeCombinationTranslators[$combiner]($this->nodeToXPath($xpath), $this->nodeToXPath($combinedXpath));
    }

    /**

View on GitHub (pinned to 08e2905152)