oracle/graal · error · IllegalStateException

object {} is not a static object

Error message

object {} is not a static object

What it means

JDWPContextImpl.getRefType(Object) expects its argument to be an Espresso StaticObject (the guest object representation) and returns its Klass; any other Java object is a caller bug, so it throws IllegalStateException. This is an internal debugger API contract, not a user-facing boundary.

Source

Thrown at espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/runtime/JDWPContextImpl.java:353

            return (String) UNCACHED.toDisplayString(staticObject, false);
        }
        return object.toString();
    }

    @Override
    public MethodVersionRef getMethodFromRootNode(RootNode root) {
        if (root instanceof EspressoRootNode) {
            return ((EspressoRootNode) root).getMethodVersion();
        }
        return null;
    }

    @Override
    public KlassRef getRefType(Object object) {
        if (object instanceof StaticObject) {
            return ((StaticObject) object).getKlass();
        } else {
            throw new IllegalStateException("object " + object + " is not a static object");
        }
    }

    @Override
    public KlassRef getReflectedType(Object classObject) {
        if (classObject instanceof StaticObject staticObject) {
            if (staticObject.getKlass().getType() == Types.java_lang_Class) {
                return (KlassRef) context.getMeta().java_lang_Class_0klass.getHiddenObject(staticObject);
            }
        }
        return null;
    }

    @Override
    public KlassRef[] getNestedTypes(KlassRef klass) {
        if (klass instanceof ObjectKlass objectKlass) {
            ArrayList<KlassRef> result = new ArrayList<>();
            List<Symbol<Name>> nestedTypeNames = objectKlass.getNestedTypeNames();

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Pass only guest objects obtained from Espresso runtime APIs (StaticObject) to this method.
  2. Add an instanceof StaticObject check before calling and skip/handle non-guest values.
  3. Prefer the public JDWP/polyglot APIs instead of Espresso-internal classes.

Example fix

// before
KlassRef ref = jdwp.getRefType(maybeHostObject); // throws for host objects

// after
if (maybeHostObject instanceof StaticObject so) {
    KlassRef ref = jdwp.getRefType(so);
} else {
    // handle host-side value separately
}
Defensive patterns

Strategy: type-guard

Type guard

boolean isGuestObject(Object o) { return o instanceof com.oracle.truffle.espresso.runtime.StaticObject; }

Prevention

When it happens

Trigger: Calling getRefType with a host object, a boxed value, null-adjacent wrapper, or a polyglot Value's host receiver instead of the guest StaticObject; usually inside custom JDWP extensions or code that reached into Espresso internals.

Common situations: Tooling that reflects over Espresso runtime values and assumes raw java.lang.Object semantics; mixing host and guest object models in a debugger integration.

Related errors


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