apple/pkl · error · DecodeException

Unexpected blank class module URI

Error message

Unexpected blank class module URI

What it means

Thrown by decodeClass when the CLASS entry's module URI string is blank. The decoder resolves the class via (name, moduleUri); without a valid module URI the reference cannot be resolved, so the payload is rejected as malformed.

Solutions

  1. Ensure the encoder writes the module URI (e.g. file:///... or pkl:base#Module) after the name
  2. Regenerate the payload with a matching Pkl version
  3. Validate the payload's integrity (check lengths/hashes) before decoding
  4. Reject blank module URIs at the producer

Example fix

// before
packer.packString(name);
// after
packer.packString(name);
packer.packString(module.getUri().toString());
Defensive patterns

Strategy: validation

Validate before calling

if (moduleUri == null || moduleUri.isBlank()) throw new IllegalArgumentException("blank class module URI");

Try / catch

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

Prevention

When it happens

Trigger: Decoding pkl-binary bytes where the second string of a CLASS entry is empty; an encoder omitting the module URI; corruption causing a mis-split of the string fields.

Common situations: Third-party encoders missing the URI field; files truncated mid-entry; decoder expecting a newer CLASS layout than the encoder produced.

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/fd26291b4d30b674. Report an issue: GitHub.

Appendix: source

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

    assertLength(PklBinaryCode.REGEX, len, 1);
    currPath.push("'regex");
    var result = doDecodeRegex(Pattern.compile(unpacker.unpackString()));
    unpacker.skipValue(len - 2);
    currPath.pop();
    return result;
  }

  private Object decodeClass(int len) throws IOException {
    assertLength(PklBinaryCode.CLASS, len, 2);
    currPath.push("'class");

    var name = unpacker.unpackString();
    if (name.isBlank()) {
      throw new DecodeException("Unexpected blank class name");
    }
    var moduleUriString = unpacker.unpackString();
    if (moduleUriString.isBlank()) {
      throw new DecodeException("Unexpected blank class module URI");
    }
    var moduleUri = URI.create(moduleUriString);

    var result = doDecodeClass(name, moduleUri);
    unpacker.skipValue(len - 3);
    currPath.pop();
    return result;
  }

  private Object decodeTypeAlias(int len) throws IOException {
    assertLength(PklBinaryCode.TYPEALIAS, len, 2);
    currPath.push("'typealias");

    var name = unpacker.unpackString();
    if (name.isBlank()) {
      throw new DecodeException("Unexpected blank typealias name");
    }
    var moduleUriString = unpacker.unpackString();

View on GitHub (pinned to f3efcbfc9b)