oracle/graal · error · RuleParseError

Unknown node type

Error message

Unknown node type: ${token}

What it means

Thrown by RuleParser.parseType when a token starting with an uppercase letter is not found in knownTypes, the map of node types discovered from @MatchableNode-annotated classes during annotation processing. Uppercase-initial tokens are treated as node type names; lowercase ones are captured variable names. An unknown uppercase token therefore means the type was never registered as matchable (or is misspelled).

Solutions

  1. Verify the exact simple name against the node class (case-sensitive).
  2. Ensure the referenced node class is annotated with @MatchableNode so the processor registers it.
  3. If the type lives in another package, check the processor's requiredPackages/scan configuration makes it visible in this compilation.

Example fix

// before
@MatchRule("add(x, y)")  // typo, also parsed as name not type

// after
@MatchRule("Add(x, y)")
Defensive patterns

Strategy: try-catch

Try / catch

Compile-time only. Tooling can map 'Unknown node type: X' to a search for class X and check whether it carries @MatchableNode.

Prevention

When it happens

Trigger: Referencing a node class in @MatchRule that lacks @MatchableNode (or whose declaring class was not scanned in this compilation round), or a simple typo: "add(x, y)" vs "Add(x, y)", "Ad(x, y)". knownTypes.get(token) returning null triggers the error.

Common situations: Matching on a node type from another suite/package not annotated @MatchableNode; renaming a node class and missing a rule; case typos; using a type's fully-qualified name where the simple name is expected.

Related errors


AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14). Data as JSON: /api/errors/826f02596d5b54c5. Report an issue: GitHub.

Appendix: source

Thrown at compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/core/match/processor/MatchProcessor.java:188

                    }
                }
                if (peek(")").equals(")")) {
                    next();
                    return descriptor;
                }
                throw new RuleParseError("Too many arguments to " + descriptor.nodeType.nodeClass);
            }
            throw new RuleParseError("Extra tokens following match pattern: " + peek(null));
        }

        private MatchDescriptor parseType(boolean forExpression) {
            TypeDescriptor type = null;
            String name = null;
            if (Character.isUpperCase(peek("node type or name").charAt(0))) {
                String token = next();
                type = knownTypes.get(token);
                if (type == null) {
                    throw new RuleParseError("Unknown node type: " + token);
                }
                if (peek("=").equals("=")) {
                    next();
                    name = next();
                }
                originatingElements.addAll(type.originatingElements);
            } else if (Character.isLowerCase(peek("name").charAt(0))) {
                name = next();
                type = valueType;
            } else {
                throw new RuleParseError("Unexpected token \"%s\" when looking for name or node type", peek(null));
            }
            requiredPackages.add(type.nodePackage);
            if (name != null) {
                if (!capturedNames.contains(name)) {
                    capturedNames.add(name);
                    capturedTypes.add(type);
                } else {

View on GitHub (pinned to a66e9ccd1d)