{"record":{"id":"723288cb9661a231","repo":"oracle/graal","slug":"invalid-guest-type","errorCode":null,"errorMessage":"Invalid guest type","messagePattern":"Invalid guest type","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"compiler/src/jdk.graal.compiler.hostvmaccess/src/jdk/graal/compiler/hostvmaccess/HostVMAccess.java","lineNumber":552,"sourceCode":"        return switch (kind) {\n            case Boolean -> JavaConstant.forBoolean(unsafe.getByte(array, absoluteOffset) != 0);\n            case Byte -> JavaConstant.forByte(unsafe.getByte(array, absoluteOffset));\n            case Short -> JavaConstant.forShort(unsafe.getShort(array, absoluteOffset));\n            case Char -> JavaConstant.forChar(unsafe.getChar(array, absoluteOffset));\n            case Int -> JavaConstant.forInt(unsafe.getInt(array, absoluteOffset));\n            case Long -> JavaConstant.forLong(unsafe.getLong(array, absoluteOffset));\n            case Float -> JavaConstant.forFloat(unsafe.getFloat(array, absoluteOffset));\n            case Double -> JavaConstant.forDouble(unsafe.getDouble(array, absoluteOffset));\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        Class<?> guestClass = providers.getSnippetReflection().originalClass(Objects.requireNonNull(guestType));\n        if (guestClass == null || !guestClass.isInterface()) {\n            throw new IllegalArgumentException(\"Invalid guest type\");\n        }\n        /* There is no fast-path for guestClass == hostClass due to exception handling */\n        HostProxyHandler handler = new HostProxyHandler(hostTarget, getHostProxyMethodMap(hostTarget.getClass(), guestClass));\n        Object guestHostProxy = Proxy.newProxyInstance(guestClass.getClassLoader(), new Class<?>[]{guestClass}, handler);\n        return providers.getSnippetReflection().forObject(guestHostProxy);\n    }\n\n    @Override\n    public Throwable unwrapHostProxyException(JavaConstant guestWrapper) {\n        Objects.requireNonNull(guestWrapper);\n        HostProxyExceptionImpl e = providers.getSnippetReflection().asObject(HostProxyExceptionImpl.class, guestWrapper);\n        if (e == null) {\n            return null;\n        }\n        return e.getCause();\n    }\n\n    private Map<Method, MethodHandle> getHostProxyMethodMap(Class<?> hostClass, Class<?> guestClass) {","sourceCodeStart":534,"sourceCodeEnd":570,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler.hostvmaccess/src/jdk/graal/compiler/hostvmaccess/HostVMAccess.java#L534-L570","documentation":"createHostProxy builds a java.lang.reflect.Proxy that lets guest code call a host object through a guest-visible interface. It maps guestType back to a host Class via snippetReflection.originalClass and requires that class to exist and be an interface (Proxy.newProxyInstance can only implement interfaces). This IllegalArgumentException ('Invalid guest type') fires when the mapping returns null or a non-interface class.","triggerScenarios":"Calling VMAccess.createHostProxy(hostTarget, guestType) where guestType has no original host class (foreign/unresolved type), or maps to a class rather than an interface (trying to proxy a concrete or abstract class). Note hostTarget itself is only null-checked; the failure is about guestType.","commonSituations":"Trying to expose a host object under a guest class (not interface); passing a ResolvedJavaType resolved by a different JVMCI runtime so originalClass returns null; guest types for annotation types or arrays which cannot be proxied.","solutions":["Pass a ResolvedJavaType that resolves to a host interface: verify originalClass(type) != null && originalClass(type).isInterface() before calling","Extract an interface for the host object's API and use that interface type as guestType","Ensure the guest type comes from the same providers/runtime as this VMAccess so originalClass can map it"],"exampleFix":"// before\nJavaConstant proxy = vmAccess.createHostProxy(hostObj, concreteClassType); // class, not interface\n\n// after\nClass<?> hostIface = providers.getSnippetReflection().originalClass(guestType);\nif (hostIface == null || !hostIface.isInterface()) {\n    throw new IllegalArgumentException(\"guestType must map to a host interface\");\n}\nJavaConstant proxy = vmAccess.createHostProxy(hostObj, guestType);","handlingStrategy":"validation","validationCode":"Class<?> hostClass = providers.getSnippetReflection().originalClass(guestType);\nif (hostClass == null || !hostClass.isInterface()) {\n    throw new IllegalArgumentException(\"guestType must map to a host interface: \" + guestType);\n}","typeGuard":"boolean proxyableGuestType(ResolvedJavaType t, SnippetReflectionProvider sr) {\n    Class<?> c = sr.originalClass(t);\n    return c != null && c.isInterface();\n}","tryCatchPattern":null,"preventionTips":["Model interop boundaries with interfaces, never classes","Validate guestType at API design time: document it must be an interface type","Ensure guest types are resolved by the same runtime that builds the proxy"],"tags":["graalvm","vmaccess","proxy","interop","interface"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}