oracle/graal · error · IOException

Missing this in serialized frame.

Error message

Missing this in serialized frame.

What it means

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.

Source

Thrown at espresso/src/org.graalvm.continuations/src/org/graalvm/continuations/FrameRecordSerializer.java:260

        }
    }

    private ContinuationImpl.FrameRecord readFrame()
                    throws IOException, NoSuchMethodException {
        assert in != null;
        // May be null if class is derived from `this`
        String holder = readHolder();
        String methodName = readMethodName();
        Object possibleThis = null;
        try {
            Object[] pointers = (Object[]) in.readObject();

            // Try to obtain type information for possible error reporting.
            // Slot zero is always primitive (bci), so this is in slot 1.
            if (holder == null) {
                possibleThis = pointers.length > THIS_POS ? pointers[THIS_POS] : null;
                if (possibleThis == null) {
                    throw new IOException("Missing this in serialized frame.");
                }
                holder = possibleThis.getClass().getName();
            }

            long[] primitives = (long[]) in.readObject();
            Method method = readMethodNameAndTypes(loader, possibleThis, methodName, holder);
            int bci = in.readInt();
            return new ContinuationImpl.FrameRecord(pointers, primitives, method, bci);
        } catch (IOException | ClassNotFoundException e) {
            throw new IOException("Failed to deserialize frame for %s.%s().".formatted((holder == null ? "?" : holder), methodName), e);
        }
    }

    private String readMethodName() throws IOException {
        return readString();
    }

    private String readHolder() throws IOException {

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Re-serialize the continuation on the same runtime/library version and retry — the payload itself is malformed.
  2. Verify transport integrity (checksums, length) so frames cannot be silently truncated before deserialize.
  3. Confirm producer and consumer use the same org.graalvm.continuations version; slot layout (bci in slot 0, this in slot 1) is version-locked.
  4. Catch the IOException wrapper ('Failed to deserialize frame ...') and discard the continuation rather than partially resuming it.

Example fix

// before
byte[] payload = base64Decode(userSuppliedString); // may be truncated
Continuation c = Continuation.deserialize(payload, loader);

// after
byte[] payload = verifyChecksum(base64Decode(userSuppliedString));
if (payload == null) throw new IllegalArgumentException("corrupt continuation payload");
Continuation c = Continuation.deserialize(payload, loader);
Defensive patterns

Strategy: try-catch

Try / catch

try { Continuation.deserialize(bytes, loader); } catch (IOException e) { /* malformed frame: cause chain shows 'Missing this'; discard payload */ }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14). Data as JSON: /api/errors/8305ddb92af70af3. Report an issue: GitHub.