{"record":{"id":"f7c75833d121495d","repo":"oracle/graal","slug":"no-class-for","errorCode":null,"errorMessage":"No class for ","messagePattern":"No class for ","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graphio/GraphProtocol.java","lineNumber":594,"sourceCode":"                    writeShort((char) 0);\n                } else {\n                    int listSize = list.size();\n                    if (listSize != ((char) listSize)) {\n                        throw new IOException(\"Too many nodes in list: \" + list.size());\n                    }\n                    writeShort((char) listSize);\n                    for (Node edge : list) {\n                        writeNodeRef(edge);\n                    }\n                }\n            }\n        }\n    }\n\n    private NodeClass classForNode(Node node) throws IOException {\n        NodeClass clazz = findClassForNode(node);\n        if (clazz == null) {\n            throw new IOException(\"No class for \" + node);\n        }\n        return clazz;\n    }\n\n    private void writeNodeRef(Node node) throws IOException {\n        writeInt(findNodeId(node));\n    }\n\n    private void writeBlocks(Collection<? extends Block> blocks, Graph info) throws IOException {\n        if (blocks != null) {\n            for (Block block : blocks) {\n                Collection<? extends Node> nodes = findBlockNodes(info, block);\n                if (nodes == null) {\n                    writeInt(0);\n                    return;\n                }\n            }\n            writeInt(blocks.size());","sourceCodeStart":576,"sourceCodeEnd":612,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graphio/GraphProtocol.java#L576-L612","documentation":"Before serializing a node, GraphProtocol resolves its NodeClass via findClassForNode; a null result means the protocol cannot describe this node type to the reader, and it throws IOException('No class for <node>') rather than emitting an unparseable stream. The lookup fails for node classes that are not registered/visible to the dump's class mapping — typically foreign or dynamically created node types.","triggerScenarios":"Dumping a graph containing node instances whose class has no NodeClass resolvable by the configured protocol (missing/failed static TYPE initialization, node classes from a classloader the protocol cannot introspect, or proxies/anonymous node subclasses). Custom GraphProtocol subclasses whose findClassForNode does not cover all node types present.","commonSituations":"Dumping graphs from plugins/libraries that define their own node types without proper @NodeInfo/NodeClass metadata. Running under classloader setups (e.g. some test harnesses or polyglot runtimes) where reflection on node classes fails silently. Overriding findClassForNode and forgetting a category of nodes.","solutions":["Ensure every node class in the dumped graph has working NodeClass metadata (static TYPE initialized; see NodeClass.get).","If you override GraphProtocol.findClassForNode, add a branch covering the failing node type (log node.getClass() to identify it).","Initialize the node's class (Class.forName with initialize=true) before dumping so TYPE is populated.","Filter the failing nodes out of the dump (custom node filtering) if they need not be visualized."],"exampleFix":"// before\nclass MyProtocol extends GraphProtocol {\n    protected NodeClass findClassForNode(Node node) {\n        return registry.lookup(node.getClass()); // returns null for foreign nodes -> IOException\n    }\n}\n\n// after\nclass MyProtocol extends GraphProtocol {\n    protected NodeClass findClassForNode(Node node) {\n        NodeClass nc = registry.lookup(node.getClass());\n        return nc != null ? nc : NodeClass.get(node.getClass()); // fall back to TYPE metadata\n    }\n}","handlingStrategy":"try-catch","validationCode":"// ensure every node type in the graph has resolvable NodeClass metadata before dumping\nfor (Node n : graph.getNodes()) {\n    if (NodeClass.get(n.getClass()) == null) {\n        throw new IllegalStateException(\"Undumpable node type: \" + n.getClass());\n    }\n}","typeGuard":"static boolean isDumpableNodeType(Class<? extends Node> c) {\n    try {\n        return NodeClass.get(c) != null;\n    } catch (RuntimeException e) {\n        return false;\n    }\n}","tryCatchPattern":"try {\n    output.print(graph, ...);\n} catch (IOException e) {\n    if (e.getMessage().startsWith(\"No class for\")) {\n        // identify the node type from the message, initialize its class / extend findClassForNode, re-dump\n        log.warning(\"Skipping dump: \" + e.getMessage());\n    } else throw e;\n}","preventionTips":["Give all custom node classes proper @NodeInfo metadata and initialized TYPE fields.","Extend findClassForNode coverage whenever you add node types to a custom protocol.","Test dump paths for every node type your plugin introduces."],"tags":["java","graal","graphio","nodeclass","dumping","reflection","metadata"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}