{"record":{"id":"956281395dc4e9dc","repo":"oracle/graal","slug":"could-not-parse-bytes-for-type-annotations","errorCode":null,"errorMessage":"Could not parse bytes for type annotations","messagePattern":"Could not parse bytes for type annotations","errorType":"exception","errorClass":"AnnotationFormatError","httpStatus":null,"severity":"error","filePath":"compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/annotation/TypeAnnotationValueParser.java","lineNumber":160,"sourceCode":"                short length = buf.getShort();\n                for (int i = 0; i < length; ++i) {\n                    buf.getShort();\n                    buf.getShort();\n                    buf.getShort();\n                }\n                break;\n            }\n            case CAST:\n            case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:\n            case METHOD_INVOCATION_TYPE_ARGUMENT:\n            case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:\n            case METHOD_REFERENCE_TYPE_ARGUMENT: {\n                buf.getShort();\n                buf.get();\n                break;\n            }\n            default:\n                throw new AnnotationFormatError(\"Could not parse bytes for type annotations\");\n        }\n        int endPos = buf.position();\n        byte[] targetInfo = new byte[endPos - startPos];\n        buf.position(startPos).get(targetInfo).position(endPos);\n        return targetInfo;\n    }\n\n    private static byte[] parseTypePath(ByteBuffer buf) {\n        int startPos = buf.position();\n        int depth = buf.get() & 0xFF;\n        for (int i = 0; i < depth; i++) {\n            buf.get();\n            buf.get();\n        }\n        int endPos = buf.position();\n        byte[] typePath = new byte[endPos - startPos];\n        buf.position(startPos).get(typePath).position(endPos);\n        return typePath;","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/annotation/TypeAnnotationValueParser.java#L142-L178","documentation":"JNIMethodScope keeps a per-thread stack of active JNI scopes in a ThreadLocal. scope() returns the innermost scope but throws IllegalStateException if the thread currently has no open scope: the calling code is executing JNI helper logic outside any registered native-method call. The scope must be entered first with new JNIMethodScope(name, env) (typically try-with-resources).","triggerScenarios":"Calling JNIMethodScope.scope() (directly or via JNIUtil helpers that need the current scope) from a thread that never opened a scope; calling it after close() popped the last scope; invoking scope-dependent helpers from a helper/GC thread rather than the JNI-calling thread.","commonSituations":"Refactoring JNI glue so a helper runs before the scope is opened; asynchronous callbacks delivered on a different thread than the one that entered the scope; unit tests calling scope-dependent utilities without setup.","solutions":["Wrap the JNI work in try (JNIMethodScope scope = new JNIMethodScope(\"name\", env)) { ... } before any code that calls scope().","For optional lookup use currentScope()-style access (the null-returning variant shown above scope()) and only fall back to scope() when non-null.","Ensure the same thread that enters the scope performs the JNI work; pass the scope explicitly to helpers if needed."],"exampleFix":"// before\nJNIMethodScope s = JNIMethodScope.scope(); // throws if no scope open\nhandleCall(env);\n\n// after\ntry (JNIMethodScope s = new JNIMethodScope(\"handleCall\", env)) {\n    handleCall(env); // helpers inside may call JNIMethodScope.scope()\n}","handlingStrategy":"validation","validationCode":"// Use the null-tolerant current-scope accessor before calling scope():\n// (the class exposes leaf lookup; if you only have scope(), guard by tracking your own enter/exit)\nboolean inScope = myScopeDepth > 0; // maintained by your try-with-resources wrapper\nif (!inScope) throw new IllegalStateException(\"JNI helper called outside a JNIMethodScope\");","typeGuard":null,"tryCatchPattern":"try {\n    JNIMethodScope s = JNIMethodScope.scope();\n} catch (IllegalStateException e) {\n    // scope not opened on this thread: open one (try-with-resources) and retry once\n}","preventionTips":["Enter a JNIMethodScope at the outermost JNI boundary of each thread's call path.","Pass the scope explicitly to helpers instead of relying on the ThreadLocal."],"tags":["jni","scope","thread-local","lifecycle"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}