{"record":{"id":"6f191c09158e7b12","repo":"oracle/graal","slug":"failed-to-deserialize-frame-for-s-s","errorCode":null,"errorMessage":"Failed to deserialize frame for %s.%s().","messagePattern":"Failed to deserialize frame for (.+?)\\.(.+?)\\(\\)\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"espresso/src/org.graalvm.continuations/src/org/graalvm/continuations/FrameRecordSerializer.java","lineNumber":270,"sourceCode":"        try {\n            Object[] pointers = (Object[]) in.readObject();\n\n            // Try to obtain type information for possible error reporting.\n            // Slot zero is always primitive (bci), so this is in slot 1.\n            if (holder == null) {\n                possibleThis = pointers.length > THIS_POS ? pointers[THIS_POS] : null;\n                if (possibleThis == null) {\n                    throw new IOException(\"Missing this in serialized frame.\");\n                }\n                holder = possibleThis.getClass().getName();\n            }\n\n            long[] primitives = (long[]) in.readObject();\n            Method method = readMethodNameAndTypes(loader, possibleThis, methodName, holder);\n            int bci = in.readInt();\n            return new ContinuationImpl.FrameRecord(pointers, primitives, method, bci);\n        } catch (IOException | ClassNotFoundException e) {\n            throw new IOException(\"Failed to deserialize frame for %s.%s().\".formatted((holder == null ? \"?\" : holder), methodName), e);\n        }\n    }\n\n    private String readMethodName() throws IOException {\n        return readString();\n    }\n\n    private String readHolder() throws IOException {\n        assert in != null;\n        if (in.readBoolean()) {\n            return null;\n        } else {\n            return readString();\n        }\n    }\n\n    private Method readMethodNameAndTypes(ClassLoader classLoader, Object possibleThis, String name, String holder)\n                    throws IOException, ClassNotFoundException, NoSuchMethodException {","sourceCodeStart":252,"sourceCodeEnd":288,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/espresso/src/org.graalvm.continuations/src/org/graalvm/continuations/FrameRecordSerializer.java#L252-L288","documentation":"The wrapper IOException ('Failed to deserialize frame for %s.%s().') that readFrame throws after catching any IOException or ClassNotFoundException raised while rebuilding a single stack frame. The real failure is attached as the cause: typically a ClassNotFoundException when the frame's declaring class is not loadable by the classloader supplied to withLoader (defaults to the thread context classloader), or one of the embedded frame-format errors ('Missing this', 'Unexpected kind').","triggerScenarios":"Deserializing a continuation whose stack includes a class not present on the loader passed to Continuation.deserialize/readObjectExternalImpl; the app server or deserializing thread has a context classloader that cannot see the application's classes.","commonSituations":"Resuming a continuation on a node where a newer class layout or renamed class exists; deserializing from a background thread whose context classloader is the system loader instead of the app loader; OSGi/modular deployments where the frame's classes live in a bundle not wired to the reader.","solutions":["Read the cause: if ClassNotFoundException, ensure the frame's class (holder from the message) is on the deserializing classloader — pass an explicit loader covering all classes on the continuation's stack, not the implicit context classloader.","Set Thread.currentThread().setContextClassLoader(appLoader) before deserialize if you rely on the default.","Keep class versions identical between the runtime that suspended and the one that resumes (no renames/removals of methods that appear on the stack).","Catch IOException from deserialize and quarantine the payload with the frame coordinates from the message for diagnosis."],"exampleFix":"// before\nContinuation c = Continuation.deserialize(bytes, null); // falls back to ctx loader, misses app classes\n\n// after\nContinuation c = Continuation.deserialize(bytes, appClassLoader); // loader that sees every frame's class","handlingStrategy":"validation","validationCode":"// before deserialize, confirm every class named in the payload is loadable\nfor (String cn : payloadClassNames(bytes)) {\n    Class.forName(cn, false, appClassLoader); // throws ClassNotFoundException early with a clear message\n}","typeGuard":null,"tryCatchPattern":"try { Continuation.deserialize(bytes, appClassLoader); } catch (IOException e) { if (e.getCause() instanceof ClassNotFoundException cnf) { /* class missing on loader: fix classpath/layer */ } }","preventionTips":["Always pass an explicit ClassLoader that sees all classes on the continuation stack; do not rely on the thread context loader.","Set the context classloader appropriately if you must rely on the default.","Treat methods on suspendable stacks as a serialization contract: no renames/signature changes across deployments."],"tags":["serialization","continuations","classloader","deserialization"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}