{"record":{"id":"ff24a902ff47910c","repo":"oracle/graal","slug":"invalid-guest-type-ff24a9","errorCode":null,"errorMessage":"Invalid guest type","messagePattern":"Invalid guest type","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"espresso-compiler-stub/src/com.oracle.truffle.espresso.vmaccess/src/com/oracle/truffle/espresso/vmaccess/EspressoExternalVMAccess.java","lineNumber":1075,"sourceCode":"        }\n        return switch (kind) {\n            case Boolean -> JavaConstant.forBoolean(value.readBufferByte(offset) != 0);\n            case Byte -> JavaConstant.forByte(value.readBufferByte(offset));\n            case Short -> JavaConstant.forShort(value.readBufferShort(ByteOrder.nativeOrder(), offset));\n            case Char -> JavaConstant.forChar((char) value.readBufferShort(ByteOrder.nativeOrder(), offset));\n            case Int -> JavaConstant.forInt(value.readBufferInt(ByteOrder.nativeOrder(), offset));\n            case Long -> JavaConstant.forLong(value.readBufferLong(ByteOrder.nativeOrder(), offset));\n            case Float -> JavaConstant.forFloat(value.readBufferFloat(ByteOrder.nativeOrder(), offset));\n            case Double -> JavaConstant.forDouble(value.readBufferDouble(ByteOrder.nativeOrder(), offset));\n            default -> throw new IllegalArgumentException(\"Unsupported kind: \" + kind);\n        };\n    }\n\n    @Override\n    public JavaConstant createHostProxy(Object hostTarget, ResolvedJavaType guestType) {\n        Objects.requireNonNull(hostTarget);\n        if (!(Objects.requireNonNull(guestType) instanceof EspressoExternalResolvedInstanceType espressoGuestType) || !espressoGuestType.isInterface()) {\n            throw new IllegalArgumentException(\"Invalid guest type\");\n        }\n        Value hostProxy = hostProxies.createHostProxy(hostTarget, espressoGuestType);\n        return new EspressoExternalObjectConstant(this, hostProxy);\n    }\n\n    @Override\n    public Throwable unwrapHostProxyException(JavaConstant guestWrapper) {\n        Objects.requireNonNull(guestWrapper);\n        if (!(guestWrapper instanceof EspressoExternalObjectConstant espressoWrapper)) {\n            return null;\n        }\n        Throwable throwable = maybeUnwrapHostException(espressoWrapper.getValue());\n        if (throwable == null) {\n            return null;\n        }\n        return throwable;\n    }\n","sourceCodeStart":1057,"sourceCodeEnd":1093,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/espresso-compiler-stub/src/com.oracle.truffle.espresso.vmaccess/src/com/oracle/truffle/espresso/vmaccess/EspressoExternalVMAccess.java#L1057-L1093","documentation":"Thrown by EspressoExternalVMAccess.createHostProxy when the guestType argument is not usable as a proxy interface. Espresso implements host interop with Java dynamic proxies, so the guest type must be a resolved Espresso type (EspressoExternalResolvedInstanceType) and it must be an interface; a class, array, primitive, or a ResolvedJavaType coming from a different compiler backend is rejected with IllegalArgumentException.","triggerScenarios":"Calling vmAccess.createHostProxy(hostTarget, guestType) where guestType is a non-interface ResolvedJavaType (class, array, primitive), or a ResolvedJavaType that was not resolved through the Espresso external VM access API (e.g. obtained from a HotSpot/Economy Graal backend instead of EspressoExternalVMAccess).","commonSituations":"Passing a concrete guest class instead of the interface the guest code will cast the proxy to; mixing ResolvedJavaType instances from another Graal backend (graal compiler SDK types) with Espresso's external access API; passing a type resolved before the Espresso context was initialized.","solutions":["Pass an interface type that the guest code uses to interact with the host object, not the host object's class","Obtain the ResolvedJavaType from Espresso itself (e.g. vmAccess/EspressoExternalResolvedInstanceType lookup) instead of an external compiler backend","Check guestType instanceof EspressoExternalResolvedInstanceType t && t.isInterface() before calling createHostProxy and fail with your own descriptive error"],"exampleFix":"// before\nJavaConstant proxy = vmAccess.createHostProxy(hostObj, someClassType); // someClassType is a class\n\n// after\nif (!(guestType instanceof EspressoExternalResolvedInstanceType it) || !it.isInterface()) {\n    throw new IllegalArgumentException(\"guestType must be an Espresso-resolved interface: \" + guestType);\n}\nJavaConstant proxy = vmAccess.createHostProxy(hostObj, it);","handlingStrategy":"type-guard","validationCode":"if (!(guestType instanceof EspressoExternalResolvedInstanceType iface) || !iface.isInterface()) {\n    throw new IllegalArgumentException(\"guestType must be an Espresso-resolved interface, got: \" + guestType);\n}","typeGuard":"static boolean isUsableGuestInterface(ResolvedJavaType t) {\n    return t instanceof EspressoExternalResolvedInstanceType e && e.isInterface();\n}","tryCatchPattern":"catch (IllegalArgumentException e) { /* surface which type was passed and why it is not an interface */ }","preventionTips":["Always resolve guest types through the same EspressoExternalVMAccess instance that builds the proxy","Pass the interface the guest code will use, never an implementation class or array type"],"tags":["espresso","host-interop","proxy","type-check"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}