{"record":{"id":"e97a2ed0faa6be87","repo":"oracle/graal","slug":"should-be-recognized-as-signature","errorCode":null,"errorMessage":"Should be recognized as signature: ","messagePattern":"Should be recognized as signature: ","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graphio/GraphProtocol.java","lineNumber":761,"sourceCode":"                if (enumValueNames != null) {\n                    writeByte(ENUM_KLASS);\n                    writeInt(enumValueNames.length);\n                    for (String o : enumValueNames) {\n                        writePoolObject(o);\n                    }\n                } else {\n                    writeByte(KLASS);\n                }\n                break;\n            }\n            case POOL_METHOD: {\n                ResolvedJavaMethod method = (ResolvedJavaMethod) found[0];\n                Objects.requireNonNull(method);\n                writePoolObject(findMethodDeclaringClass(method));\n                writePoolObject(findMethodName(method));\n                final Signature methodSignature = findMethodSignature(method);\n                if (findSignature(methodSignature) == null) {\n                    throw new IOException(\"Should be recognized as signature: \" + methodSignature + \" for \" + method);\n                }\n                writePoolObject(methodSignature);\n                writeInt(findMethodModifiers(method));\n                writeBytes(findMethodCode(method));\n                break;\n            }\n            case POOL_ENUM: {\n                int enumOrdinal = (int) found[0];\n                writePoolObject(findEnumClass(object));\n                writeInt(enumOrdinal);\n                break;\n            }\n            case POOL_STRING: {\n                writeString(object.toString());\n                break;\n            }\n            default:\n                throw new IllegalStateException();","sourceCodeStart":743,"sourceCodeEnd":779,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graphio/GraphProtocol.java#L743-L779","documentation":"Thrown while serializing a ResolvedJavaMethod into the graph constant pool (POOL_METHOD entry). Before writing the signature, GraphProtocol calls findSignature(methodSignature) to locate or register the signature object in its pool; if that lookup returns null, the library cannot map the object returned by findMethodSignature to any poolable signature. In practice this means the GraphStructure/protocol customization returned an object that the signature pool does not recognize (e.g. a raw method, a null-ish wrapper, or an object whose class is not handled by findSignature). The stream is aborted with an IOException because continuing would emit an unparseable pool entry.","triggerScenarios":"Subclassing GraphProtocol/ProtocolImpl (or providing a custom GraphStructure) and overriding findMethodSignature so it returns something other than an object that findSignature can resolve; dumping a graph whose nodes reference a ResolvedJavaMethod whose signature object is of an unexpected type; partial overrides where findSignature was not overridden consistently with findMethodSignature.","commonSituations":"Custom graph dumpers built on the graphio library (e.g. dumping domain-specific graphs with method-like nodes), upgrades of GraalVM where the Signature abstraction changed, and test harnesses that feed mock ResolvedJavaMethod/Signature objects into the dumper.","solutions":["Make findMethodSignature return a real Signature-compatible object and ensure findSignature recognizes the exact same object/type (both methods must agree on the signature representation).","If you replaced one of findMethodSignature/findSignature, override the matching counterpart so the pool lookup succeeds.","When dumping mocks or synthetic methods, wrap their signatures in a concrete signature type the protocol already handles (e.g. a real jdk.vm.meta Signature implementation).","Add a unit test that dumps a graph containing a method node to catch the mismatch before runtime."],"exampleFix":"// before (custom GraphStructure)\n@Override\npublic Object findMethodSignature(Object method) {\n    return method; // returns the method itself -> findSignature(method) == null -> IOException\n}\n\n// after\n@Override\npublic Signature findMethodSignature(ResolvedJavaMethod method) {\n    return method.getSignature(); // a real Signature object the pool recognizes\n}","handlingStrategy":"validation","validationCode":"// Before dumping, verify the signature round-trips through your own lookups\nSignature sig = structure.findMethodSignature(method);\nif (sig == null || protocol.findSignatureInPool(sig) == null) {\n    throw new IllegalStateException(\"Unrecognized method signature for \" + method);\n}","typeGuard":null,"tryCatchPattern":"try { protocol.dump(graph); } catch (IOException e) { if (e.getMessage().startsWith(\"Should be recognized as signature\")) { /* fix findMethodSignature/findSignature pairing */ } throw e; }","preventionTips":["Override findMethodSignature and findSignature together so they agree on the signature representation.","Unit-test dumping a graph that contains a method reference before shipping a custom GraphStructure.","Never return the method object (or ad-hoc wrappers) from signature-returning methods."],"tags":["graphio","serialization","api-contract","custom-structure"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}