{"record":{"id":"748134960895b28a","repo":"apple/pkl","slug":"unexpected-blank-object-class-name","errorCode":null,"errorMessage":"Unexpected blank object class name","messagePattern":"Unexpected blank object class name","errorType":"exception","errorClass":"DecodeException","httpStatus":null,"severity":"error","filePath":"pkl-core/src/main/java/org/pkl/core/util/pklbinary/AbstractPklBinaryDecoder.java","lineNumber":201,"sourceCode":"      case BYTES -> decodeBytes(len);\n      default -> throw new DecodeException(\"Unrecognized object code %s\", code);\n    };\n  }\n\n  private void checkCollectionLength(int length, String collectionType) {\n    if (length <= collectionSizeLimit) return;\n    throw new DecodeException(\n        \"Unable to decode %s of length %d, exceeded maximum collection size of %d\",\n        collectionType, length, collectionSizeLimit);\n  }\n\n  private Object decodeObject(int len) throws IOException {\n    assertLength(PklBinaryCode.OBJECT, len, 3);\n    currPath.push(\"'object\");\n\n    var className = unpacker.unpackString();\n    if (className.isBlank()) {\n      throw new DecodeException(\"Unexpected blank object class name\");\n    }\n    var classModuleUriString = unpacker.unpackString();\n    if (classModuleUriString.isBlank()) {\n      throw new DecodeException(\"Unexpected blank object module URI\");\n    }\n    var classModuleUri = URI.create(classModuleUriString);\n\n    var result =\n        doDecodeObject(\n            className, classModuleUri, new ObjectDecodeIterator(unpacker.unpackArrayHeader()));\n    unpacker.skipValue(len - 4);\n    currPath.pop();\n    return result;\n  }\n\n  private Object decodeMap(int len) throws IOException {\n    assertLength(PklBinaryCode.MAP, len, 1);\n    currPath.push(\"'map\");","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-core/src/main/java/org/pkl/core/util/pklbinary/AbstractPklBinaryDecoder.java#L183-L219","documentation":"Thrown by decodeObject when decoding a Pkl binary OBJECT code whose class-name string field is empty or whitespace-only. A Pkl object value must identify the class it instantiates, so a blank name means the payload is malformed or corrupt.","triggerScenarios":"Decoding pkl-binary bytes where an OBJECT entry encodes an empty string as the class name; corrupted/truncated payloads; a buggy third-party encoder writing the fields in the wrong order.","commonSituations":"Manually crafted binary payloads; encoders from incompatible Pkl versions writing fields in a different order; bit-rot or truncation shifting string boundaries.","solutions":["Inspect the binary payload around the object entry and confirm the class name is encoded correctly","Re-generate the binary payload with the matching Pkl/encoder version","Check that you are not decoding a file of a different format as pkl-binary","Reject blank class names at the producer side before emitting the payload"],"exampleFix":"// before (encoder side)\npacker.packString(\"\");\n// after\npacker.packString(\"my.pkg.MyClass\");","handlingStrategy":"validation","validationCode":"// producer-side guard before packing\nif (className == null || className.isBlank()) throw new IllegalArgumentException(\"blank class name\");","typeGuard":null,"tryCatchPattern":"try {\n  return decoder.decode(bytes);\n} catch (DecodeException e) {\n  if (e.getMessage().contains(\"blank object class name\")) {\n    throw new MalformedPklBinaryException(e);\n  }\n  throw e;\n}","preventionTips":["Always encode className before moduleUri and members, in that order","Validate strings are non-blank on the encoder side","Keep encoder and decoder on the same Pkl version","Check payload integrity when files come from network or disk"],"tags":["pkl","binary-decoder","corrupt-payload"],"backgroundTag":"empty-required-field","analyzedSha":"f3efcbfc9b60d30053b0536d664948d7aa1b8673","analyzedAt":"2026-09-08T13:10:45.570Z","contentChangedAt":"2026-09-08T13:10:45.570Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}