oracle/graal · error · IllegalArgumentException

Element should be an espresso object constant, got

Error message

Element {} should be an espresso object constant, got {}

What it means

In asArrayConstant's object-array branch, every non-null element must be an EspressoExternalObjectConstant so the guest Value can be stored into the guest array with setArrayElement. An element constant from another JVMCI backend (or a primitive-boxed constant where an object constant was expected) has no guest Value and throws IllegalArgumentException naming the offending index.

Solutions

  1. Produce every element through this Espresso provider (its constant reflection / previous asArrayConstant results).
  2. For nested arrays, build each inner array with asArrayConstant first so elements are EspressoExternalObjectConstant.
  3. Filter or convert foreign constants before the call; keep nulls (they are skipped).

Example fix

// before
elems[i] = JavaConstant.forObject(hostString);

// after
elems[i] = espressoConstantReflection.forObject(guestString); // same context
Defensive patterns

Strategy: validation

Validate before calling

for (int i = 0; i < elements.length; i++) {
    JavaConstant c = elements[i];
    if (!c.isNull() && !(c instanceof EspressoExternalObjectConstant)) {
        // convert or reject before the call
    }
}

Type guard

static boolean allEspressoOrNull(JavaConstant[] elems) {
    for (JavaConstant c : elems) {
        if (!c.isNull() && !(c instanceof EspressoExternalObjectConstant)) return false;
    }
    return true;
}

Try / catch

catch (IllegalArgumentException e) naming the index — use the index to locate and re-create the offending element through the Espresso provider, then retry.

Prevention

When it happens

Trigger: Building an object array (or a multi-dimensional primitive array, dimensions > 1) where some elements are host constants, JavaConstant.forObject host values, or constants from another Espresso context.

Common situations: Mixed-origin element lists in substitutions; element constants cached from a previous provider version; multi-dimensional array construction where callers wrongly pass primitive constants instead of nested Espresso array constants.

Related errors


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

Appendix: source

Thrown at espresso-compiler-stub/src/com.oracle.truffle.espresso.vmaccess/src/com/oracle/truffle/espresso/vmaccess/EspressoExternalVMAccess.java:566

            JavaKind javaKind = elementalType.getJavaKind();
            for (int i = 0; i < elements.length; i++) {
                JavaConstant element = elements[i];
                if (javaKind != element.getJavaKind()) {
                    throw new IllegalArgumentException("Element " + i + " should be a " + javaKind + " but was " + element.getJavaKind());
                }
                if (element.isDefaultForKind()) {
                    continue;
                }
                array.setArrayElement(i, element.asBoxedPrimitive());
            }
        } else {
            for (int i = 0; i < elements.length; i++) {
                JavaConstant element = elements[i];
                if (element.isNull()) {
                    continue;
                }
                if (!(element instanceof EspressoExternalObjectConstant objectElement)) {
                    throw new IllegalArgumentException("Element " + i + " should be an espresso object constant, got " + safeGetClass(element));
                }
                try {
                    array.setArrayElement(i, objectElement.getValue());
                } catch (ClassCastException e) {
                    throw new IllegalArgumentException("Element " + i + " is not an instance of the component type", e);
                }
            }
        }
        return new EspressoExternalObjectConstant(this, array);
    }

    @Override
    public JavaConstant createPrimitiveArray(JavaKind kind, int length) {
        if (kind == null || !kind.isPrimitive() || kind == JavaKind.Void) {
            throw new IllegalArgumentException("Expected a non-void primitive kind, got " + kind);
        }
        if (length < 0) {
            throw new NegativeArraySizeException("Negative array size: " + length);

View on GitHub (pinned to a66e9ccd1d)