oracle/graal · error · IllegalArgumentException

Could not unwrap array: {}

Error message

Could not unwrap array: {}

What it means

writeArrayElement requires a real host array object: it unwraps the JavaConstant with snippetReflection.asObject(Object.class, array). If that returns null — the constant is not a materialized object constant (e.g. null, a primitive constant, a compressed placeholder, or a constant from a different/unregistered object graph) — this IllegalArgumentException is thrown. The type check passed, but the constant cannot be turned into an actual array instance.

Source

Thrown at compiler/src/jdk.graal.compiler.hostvmaccess/src/jdk/graal/compiler/hostvmaccess/HostVMAccess.java:365

            unwrappedValue = element.asBoxedPrimitive();
        } else {
            if (!element.getJavaKind().isObject()) {
                throw new IllegalArgumentException("Element " + element + " should be an object, got " + componentType);
            }
            unwrappedValue = providers.getSnippetReflection().asObject(Object.class, element);
        }
        Array.set(array, index, unwrappedValue);
    }

    @Override
    public void writeArrayElement(JavaConstant array, int index, JavaConstant element) {
        ResolvedJavaType arrayType = getProviders().getMetaAccess().lookupJavaType(array);
        if (arrayType == null || !arrayType.isArray()) {
            throw new IllegalArgumentException("Expected an array constant, got " + array);
        }
        Object asObject = providers.getSnippetReflection().asObject(Object.class, array);
        if (asObject == null) {
            throw new IllegalArgumentException("Could not unwrap array: " + array);
        }
        doWriteArrayElement(asObject, arrayType.getComponentType(), index, element);
    }

    @Override
    public ResolvedJavaMethod asResolvedJavaMethod(Constant constant) {
        SnippetReflectionProvider snippetReflection = providers.getSnippetReflection();
        Executable executable = snippetReflection.asObject(Executable.class, (JavaConstant) constant);
        if (executable != null) {
            return providers.getMetaAccess().lookupJavaMethod(executable);
        }
        return null;
    }

    @Override
    public JavaConstant asFieldConstant(ResolvedJavaField field) {
        if (field.isInternal()) {
            return null;

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Ensure the array constant originates from the same Graal runtime (forObject on the same SnippetReflectionProvider) as the VMAccess used for writing
  2. Guard with providers.getSnippetReflection().asObject(Object.class, arrayConst) != null before calling writeArrayElement
  3. If the constant is null or non-materializable, skip the write or rebuild the constant from the live array object

Example fix

// before
vmAccess.writeArrayElement(arrayConst, idx, element);

// after
Object arr = providers.getSnippetReflection().asObject(Object.class, arrayConst);
if (arr == null) {
    // constant not materializable on this host - rebuild from live object or skip
    return;
}
vmAccess.writeArrayElement(arrayConst, idx, element);
Defensive patterns

Strategy: validation

Validate before calling

Object live = providers.getSnippetReflection().asObject(Object.class, arrayConst);
if (live == null || !live.getClass().isArray()) {
    // constant not materializable - rebuild via forObject or skip
}

Try / catch

catch (IllegalArgumentException e) { if (e.getMessage().contains("Could not unwrap")) { rebuild constant from live object and retry once; } else throw e; }

Prevention

When it happens

Trigger: Calling writeArrayElement with a constant that types as an array (so the isArray check at line 361 passes) but that snippetReflection cannot materialize: JavaConstant.NULL_POINTER typed as Object[], a VM-internal placeholder, or an object constant created by a different SnippetReflectionProvider that this host does not know.

Common situations: Mixing constants from an image-build (AOT) world with the host JVM reflection world; constants obtained from a guest VM or another VMAccess instance; serialized/deserialized constants that lost their object identity.

Related errors


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