apple/pkl · error · DecodeException

Unexpected msgpack ext value

Error message

Unexpected msgpack ext value

What it means

DecodeException thrown by doDecode() when a top-level msgpack value has type EXTENSION (ext format). The Pkl binary protocol never uses msgpack extension types, so encountering one means the input is not Pkl binary data (or is from a newer/foreign producer).

Solutions

  1. Regenerate the payload with Pkl's binary encoder, which never emits ext values
  2. Remove/convert extension-typed fields before handing the stream to the Pkl decoder
  3. Verify the byte stream actually belongs to Pkl binary output
  4. Check producer and consumer protocol versions
Defensive patterns

Strategy: validation

Validate before calling

// Producers must not emit msgpack ext values on the Pkl binary channel
// convert ext-typed data (e.g. timestamps) to supported primitives before encoding

Try / catch

try {
  Object v = decoder.decode(bytes);
} catch (DecodeException e) {
  if ("Unexpected msgpack ext value".equals(e.getMessage())) {
    // upstream used ext types (e.g. msgpack timestamps); re-encode without extensions
  } else throw e;
}

Prevention

When it happens

Trigger: Feeding msgpack containing ext values (e.g. timestamps or custom typed extensions from other serializers) into the Pkl binary decoder; version/protocol mismatch introducing ext types.

Common situations: Piping data serialized by msgpack-java with ext type registries (e.g. MessagePack timestamps) into Pkl tooling; protocol confusion between services.

Related errors


AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08). Data as JSON: /api/errors/682ffbf157a1fcbc. Report an issue: GitHub.

Appendix: source

Thrown at pkl-core/src/main/java/org/pkl/core/util/pklbinary/AbstractPklBinaryDecoder.java:152

      throw new DecodeException("Unexpected EOF");
    }

    return switch (unpacker.getNextFormat().getValueType()) {
      // primitives
      case NIL -> {
        unpacker.unpackNil();
        yield doDecodeNull();
      }
      case STRING -> unpacker.unpackString();
      case INTEGER -> unpacker.unpackLong();
      case BOOLEAN -> unpacker.unpackBoolean();
      case FLOAT -> unpacker.unpackDouble();
      // non-primitive
      case ARRAY -> decodeNonPrimitive();
      // things we should never see outside a non-primitive
      case BINARY -> throw new DecodeException("Unexpected msgpack bin value");
      case MAP -> throw new DecodeException("Unexpected msgpack map value");
      case EXTENSION -> throw new DecodeException("Unexpected msgpack ext value");
    };
  }

  private Object decodeNonPrimitive() throws IOException {
    var len = unpacker.unpackArrayHeader();
    if (len < 1) {
      throw new DecodeException("Unexpected empty object array value");
    }

    var codeInt = unpacker.unpackInt();
    var code = PklBinaryCode.fromInt(codeInt);
    if (code == null) {
      throw new DecodeException("Unrecognized code 0x%x", (byte) codeInt);
    }

    return switch (code) {
      case OBJECT -> decodeObject(len);
      case MAP -> decodeMap(len);

View on GitHub (pinned to f3efcbfc9b)