apple/pkl · error · DecodeException
Expected 3 fields in object member, found
Error message
Expected 3 fields in object member, found %d
What it means
Thrown by getNext (the object-member iterator) when an object member array in the Pkl binary payload does not contain exactly 3 fields (member code plus the fields identifying the member). The binary format mandates 3 fields per member, so any other count means the payload structure is invalid or was produced by an incompatible encoder.
Solutions
- Re-encode the payload with the Pkl version matching the decoder
- Inspect the member array header in the payload and fix the encoder to pack exactly 3 fields per member
- Verify the file is not truncated or otherwise corrupted
- Pin encoder and decoder to the same Pkl version in your build/deployment
Example fix
// before packer.packArrayHeader(2); packer.packInt(code); packer.packString(name); // after packer.packArrayHeader(3); packer.packInt(code); packer.packString(name); packer.packValue(value);
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-decode sanity check: walk object members and assert each has a 3-field array header var it = new MessagePackUnpacker(new ByteArrayInputStream(bytes)); // skip to object members; for each: if (unpacker.unpackArrayHeader() != 3) fail();
Try / catch
try {
return decoder.decode(bytes);
} catch (DecodeException e) {
if (e.getMessage().startsWith("Expected 3 fields in object member")) {
throw new IncompatiblePklBinaryVersionException(e);
}
throw e;
} Prevention
- Pin encoder and decoder to the same Pkl version
- Pack exactly 3 fields per object member (code, key/name info, value)
- Round-trip test payloads across every producer upgrade
- Reject or re-fetch truncated/corrupted files before decoding
When it happens
Trigger: Decoding pkl-binary bytes where an object's members array contains 2-element or 4-element member arrays; an encoder version with a different member layout; corrupted headers changing the declared array length.
Common situations: Producer and consumer using different Pkl versions with changed OBJECT member encoding; hand-crafted payloads; truncation corrupting the member array header.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Unexpected blank class module URI
- Unexpected blank class name
- Unexpected blank object class name
- Unexpected blank object module URI
- Unexpected blank typealias module URI
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/3d7b4b771db7b402.
Report an issue: GitHub.
Appendix: source
Thrown at pkl-core/src/main/java/org/pkl/core/util/pklbinary/AbstractPklBinaryDecoder.java:430
currPath.pop();
idx++;
}
}
abstract T getNext() throws IOException;
}
protected class ObjectDecodeIterator extends DecodeIterator<DecodedObjectMember> {
ObjectDecodeIterator(int size) {
super(size);
checkCollectionLength(size, "object");
}
@Override
DecodedObjectMember getNext() throws IOException {
var memberLen = unpacker.unpackArrayHeader();
if (memberLen != 3) {
throw new DecodeException("Expected 3 fields in object member, found %d", memberLen);
}
var memberCodeInt = unpacker.unpackInt();
var memberCode = PklBinaryCode.fromInt(memberCodeInt);
if (memberCode == null) {
throw new DecodeException("Unrecognized code 0x%x", (byte) memberCodeInt);
}
DecodedObjectMember member;
switch (memberCode) {
case PROPERTY -> {
var propertyName = unpacker.unpackString();
currPath.push(propertyName);
member = new DecodedObjectMember(memberCode, propertyName, doDecode());
}
case ENTRY -> {
var entryKey = doDecode();
currPath.push(entryKey);
member = new DecodedObjectMember(memberCode, entryKey, doDecode());
}View on GitHub (pinned to f3efcbfc9b)