{"record":{"id":"8305ddb92af70af3","repo":"oracle/graal","slug":"missing-this-in-serialized-frame","errorCode":null,"errorMessage":"Missing this in serialized frame.","messagePattern":"Missing this in serialized frame\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"espresso/src/org.graalvm.continuations/src/org/graalvm/continuations/FrameRecordSerializer.java","lineNumber":260,"sourceCode":"        }\n    }\n\n    private ContinuationImpl.FrameRecord readFrame()\n                    throws IOException, NoSuchMethodException {\n        assert in != null;\n        // May be null if class is derived from `this`\n        String holder = readHolder();\n        String methodName = readMethodName();\n        Object possibleThis = null;\n        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 {","sourceCodeStart":242,"sourceCodeEnd":278,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/espresso/src/org.graalvm.continuations/src/org/graalvm/continuations/FrameRecordSerializer.java#L242-L278","documentation":"Thrown as IOException by FrameRecordSerializer.readFrame: the frame was written with holder == null (meaning 'derive the holder class from the receiver', the lambda case), but slot THIS_POS of the deserialized pointers array is null, so the class cannot be recovered. The format contract is that holder-less frames must carry `this`; a null `this` breaks the round-trip and the reader aborts before constructing the FrameRecord.","triggerScenarios":"Deserializing a frame whose pointers array is shorter than THIS_POS or has null at THIS_POS while the holder string was omitted; produced by a corrupted stream, an incompatible writer version, or a payload that was written with a receiver that serialized as null.","commonSituations":"Payload corruption in transit (truncation, partial write, bad base64 round-trip); deserializing with a different library version whose slot layout for THIS_POS differs; test payloads hand-edited to omit the holder.","solutions":["Re-serialize the continuation on the same runtime/library version and retry — the payload itself is malformed.","Verify transport integrity (checksums, length) so frames cannot be silently truncated before deserialize.","Confirm producer and consumer use the same org.graalvm.continuations version; slot layout (bci in slot 0, this in slot 1) is version-locked.","Catch the IOException wrapper ('Failed to deserialize frame ...') and discard the continuation rather than partially resuming it."],"exampleFix":"// before\nbyte[] payload = base64Decode(userSuppliedString); // may be truncated\nContinuation c = Continuation.deserialize(payload, loader);\n\n// after\nbyte[] payload = verifyChecksum(base64Decode(userSuppliedString));\nif (payload == null) throw new IllegalArgumentException(\"corrupt continuation payload\");\nContinuation c = Continuation.deserialize(payload, loader);","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { Continuation.deserialize(bytes, loader); } catch (IOException e) { /* malformed frame: cause chain shows 'Missing this'; discard payload */ }","preventionTips":["Protect payloads with checksums so truncation is detected before deserialization.","Never hand-edit frame contents; holder-less frames must carry `this` in slot THIS_POS.","Keep writer and reader library versions identical."],"tags":["serialization","continuations","corrupt-stream","deserialization"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}