oracle/graal · error · ElementException

Node class must have at least one protected constructor

Error message

Node class must have at least one protected constructor

What it means

A @NodeInfo node class must expose at least one constructor that is public or protected. If all declared constructors are private (or the loop never finds a non-private one), the instantiation machinery generated for the node has no usable constructor, so GraphNodeVerifier throws this ElementException on the class itself. Private constructors are allowed only alongside at least one accessible constructor.

Source

Thrown at compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/nodeinfo/processor/GraphNodeVerifier.java:222

        return null;
    }

    void verify(TypeElement node) {
        scanFields(node);

        boolean foundValidConstructor = false;
        for (ExecutableElement constructor : ElementFilter.constructorsIn(node.getEnclosedElements())) {
            if (constructor.getModifiers().contains(PRIVATE)) {
                continue;
            } else if (!constructor.getModifiers().contains(PUBLIC) && !constructor.getModifiers().contains(PROTECTED)) {
                throw new ElementException(constructor, "Node class constructor must be public or protected");
            }

            foundValidConstructor = true;
        }

        if (!foundValidConstructor) {
            throw new ElementException(node, "Node class must have at least one protected constructor");
        }
    }
}

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Widen at least one constructor to protected (the idiomatic choice for nodes) or public.
  2. Keep private constructors only as additional helpers, never as the sole ones.
  3. Rebuild to confirm the processor accepts the class.

Example fix

// before
private MyNode() {
    super(TYPE, ...);
}

// after
protected MyNode() {
    super(TYPE, ...);
}
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: foundValidConstructor stays false after iterating all constructors — i.e. every constructor has modifiers.contains(PRIVATE) (GraphNodeVerifier.java:210-223). Example: a singleton-style node with only 'private MyNode() { ... }'.

Common situations: Singleton/utility-style node classes with only private constructors; making constructors private to force factory creation; refactoring away the protected constructor during cleanup.

Related errors


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