symfony/css-selector · error · ExpressionErrorException
Node " " not supported.
Error message
Node "%s" not supported.
What it means
Translator::nodeToXPath() dispatches a selector AST node to a registered node translator via $this->nodeTranslators, keyed by the node's name (getNodeName()). If the node name has no registered translator, an ExpressionErrorException is thrown. In practice this only happens when a custom NodeInterface implementation is fed to the translator, since the parser only produces node types the default translator map covers.
Solutions
- Register a translator for the node by adding an extension that maps the node name to a callable in nodeTranslators.
- Only feed the translator nodes produced by Symfony\Component\CssSelector\Node nodes from the bundled parser, not custom or foreign node objects.
- Verify getNodeName() of the offending node matches an existing translator key (e.g. 'Element', 'Class', 'Identifier', 'Attribute', 'CombinedSelector', 'Function', 'Hash', 'PseudoClass', 'Selector', 'Root').
Example fix
// before $translator->selectorToXPath(new MyCustomNode()); // throws // after $translator = $translator->extension(new MyNodeExtension()); // registers translator for the custom node $translator->selectorToXPath(new MyCustomNode()); // works
Defensive patterns
Strategy: try-catch
Validate before calling
// before translating
if (!in_array($node->getNodeName(), ['Element','Identifier','Attribute','Class','Hash','CombinedSelector','Function','PseudoClass','Selector','Root'], true)) {
throw new \InvalidArgumentException('Unsupported node: ' . $node->getNodeName());
} Type guard
function isTranslatableNode(Symfony\Component\CssSelector\Node\NodeInterface $node): bool {
return isset($this->nodeTranslators[$node->getNodeName()]);
} Try / catch
use Symfony\Component\CssSelector\Exception\ExpressionErrorException;
try {
$xpath = $translator->selectorToXPath($selector);
} catch (ExpressionErrorException $e) {
// log unsupported node, skip or fall back to a simpler selector
} Prevention
- Only pass nodes produced by the bundled CssSelector parser to the translator
- Register every custom node type through a Translator extension before use
- Assert node names against the translator map in unit tests for custom extensions
When it happens
Trigger: Calling Translator::nodeToXPath() (directly or via selectorToXPath / addCombination / addRelativeCombination) with a NodeInterface whose getNodeName() is not a key in the translator's nodeTranslators map — e.g. a custom node class or a node from a mismatched parser version.
Common situations: Custom CSS selector extensions that add new AST node types without registering a node translator via Translator::extension(); passing hand-built node objects to selectorToXPath(); upgrading Symfony CssSelector so parser node names no longer match a customized translator map.
Related errors
- "*:nth-of-type()" is not implemented.
- "*:first-of-type" is not implemented.
- "*:last-of-type" is not implemented.
- Pseudo-elements are not supported.
- Combiner " " not supported.
AI-assisted analysis of symfony/css-selector@08e2905152 (2026-09-14).
Data as JSON: /api/errors/85881ecb774e550f.
Report an issue: GitHub.
Appendix: source
Thrown at XPath/Translator.php:157
}
/**
* @return $this
*/
public function registerParserShortcut(ParserInterface $shortcut): static
{
$this->shortcutParsers[] = $shortcut;
return $this;
}
/**
* @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));
}
/**View on GitHub (pinned to 08e2905152)