apple/pkl · error · DecodeException

Unexpected blank object module URI

Error message

Unexpected blank object module URI

What it means

Thrown by decodeObject when the OBJECT entry's module URI string (the URI of the module declaring the object's class) is empty or whitespace-only. The decoder needs a valid module URI to resolve the class, so a blank value is treated as malformed input.

Solutions

  1. Regenerate the payload with a matching Pkl encoder version
  2. Verify the encoder always writes className, moduleUri, then members in order
  3. Confirm the input file is a genuine Pkl binary and not truncated
  4. Add producer-side validation that the module URI is non-blank

Example fix

// before
packer.packString(className);
packer.packString(""); // module URI missing
// after
packer.packString(className);
packer.packString(module.getUri().toString());
Defensive patterns

Strategy: validation

Validate before calling

// producer-side guard
if (moduleUri == null || moduleUri.isBlank()) throw new IllegalArgumentException("blank module URI");

Try / catch

try {
  return decoder.decode(bytes);
} catch (DecodeException e) {
  if (e.getMessage().contains("blank object module URI")) {
    throw new MalformedPklBinaryException(e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Decoding pkl-binary bytes where the second string field of an OBJECT entry is blank; payloads produced by an encoder that skipped the module-URI field; corruption shifting field boundaries.

Common situations: Hand-written encoders omitting the module URI; truncated files; decoding with a decoder version that expects a different OBJECT layout than the encoder used.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

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

  private void checkCollectionLength(int length, String collectionType) {
    if (length <= collectionSizeLimit) return;
    throw new DecodeException(
        "Unable to decode %s of length %d, exceeded maximum collection size of %d",
        collectionType, length, collectionSizeLimit);
  }

  private Object decodeObject(int len) throws IOException {
    assertLength(PklBinaryCode.OBJECT, len, 3);
    currPath.push("'object");

    var className = unpacker.unpackString();
    if (className.isBlank()) {
      throw new DecodeException("Unexpected blank object class name");
    }
    var classModuleUriString = unpacker.unpackString();
    if (classModuleUriString.isBlank()) {
      throw new DecodeException("Unexpected blank object module URI");
    }
    var classModuleUri = URI.create(classModuleUriString);

    var result =
        doDecodeObject(
            className, classModuleUri, new ObjectDecodeIterator(unpacker.unpackArrayHeader()));
    unpacker.skipValue(len - 4);
    currPath.pop();
    return result;
  }

  private Object decodeMap(int len) throws IOException {
    assertLength(PklBinaryCode.MAP, len, 1);
    currPath.push("'map");
    var result = doDecodeMap(new MapDecodeIterator(unpacker.unpackMapHeader(), "map"));
    unpacker.skipValue(len - 2);
    currPath.pop();
    return result;

View on GitHub (pinned to f3efcbfc9b)