{"record":{"id":"c481c1c92918b161","repo":"apple/pkl","slug":"unexpected-eof","errorCode":null,"errorMessage":"Unexpected EOF","messagePattern":"Unexpected EOF","errorType":"exception","errorClass":"DecodeException","httpStatus":null,"severity":"error","filePath":"pkl-core/src/main/java/org/pkl/core/util/pklbinary/AbstractPklBinaryDecoder.java","lineNumber":70,"sourceCode":"\n  protected AbstractPklBinaryDecoder(MessageUnpacker unpacker, int collectionSizeLimit) {\n    this.unpacker = unpacker;\n    this.collectionSizeLimit = collectionSizeLimit;\n  }\n\n  protected static class DecodeException extends RuntimeException {\n    public DecodeException(String msg, Object... args) {\n      super(new Formatter().format(msg, args).toString());\n    }\n  }\n\n  protected final Object decode() {\n    currPath = new ArrayDeque<>();\n    try {\n      try {\n        return doDecode();\n      } catch (MessageInsufficientBufferException e) {\n        throw new DecodeException(\"Unexpected EOF\", e);\n      }\n    } catch (IOException e) {\n      throw doIOFail(e);\n    } catch (MessagePackException | DecodeException e) {\n      var path = new ArrayList<String>(currPath.size());\n      for (var iter = currPath.descendingIterator(); iter.hasNext(); ) {\n        path.add(iter.next().toString());\n      }\n      Collections.reverse(path);\n      throw doFail(e, unpacker.getTotalReadBytes(), path);\n    }\n  }\n\n  private void assertLength(PklBinaryCode type, int len, int expected) {\n    if (len < expected) {\n      throw new DecodeException(\n          \"Expected %s structure to have at least %d slots, found %d\", type, expected + 1, len);\n    }","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-core/src/main/java/org/pkl/core/util/pklbinary/AbstractPklBinaryDecoder.java#L52-L88","documentation":"DecodeException wrapping a MessageInsufficientBufferException raised while reading the msgpack stream. It means the Pkl binary (msgpack-encoded) payload ended before the decoder finished reading a complete value. The library throws it from decode() whenever the underlying unpacker runs out of bytes mid-message.","triggerScenarios":"Calling decode()/first()/second() (or a subclass such as the evaluator's binary module decoder) with a truncated InputStream or byte[]; a producer (e.g. pkl server or cached module bytes) wrote fewer bytes than the msgpack header declares; the file/network stream was cut off mid-object.","commonSituations":"Corrupted or partially downloaded .pkl binary caches; version mismatch where a writer produced a newer format that the reader's unpacker mis-parses; passing an empty stream to decode(); truncation when copying evaluator output between processes.","solutions":["Regenerate or re-fetch the binary Pkl data; the payload is truncated, so it must be re-produced in full","Check that the InputStream/byte[] passed to the decoder is complete (verify byte counts / file sizes against the producer's output)","Ensure the producer and consumer use compatible Pkl versions so msgpack framing matches","If reading from a network/file stream, verify the read loop reads until EOF rather than a fixed byte count"],"exampleFix":"// before\nbyte[] buf = new byte[512];\nint n = in.read(buf);\nObject v = decoder.decode(Arrays.copyOf(buf, n)); // truncated\n// after\nObject v;\ntry (InputStream in = Files.newInputStream(path)) {\n  v = decoder.decode(in.readAllBytes()); // read to EOF\n}","handlingStrategy":"try-catch","validationCode":"// Java: verify the payload is complete before decoding\nif (bytes == null || bytes.length == 0) {\n  throw new IOException(\"empty pkl binary payload\");\n}\n// when reading streams, read fully:\nbyte[] all = in.readAllBytes();","typeGuard":"static boolean looksComplete(byte[] b) { return b != null && b.length > 0; }","tryCatchPattern":"try {\n  Object v = decoder.decode(bytes);\n} catch (DecodeException e) {\n  if (\"Unexpected EOF\".equals(e.getMessage())) {\n    // regenerate/re-fetch payload or surface a 'corrupt binary data' error\n  } else throw e;\n}","preventionTips":["Always read streams to EOF before decoding; never decode fixed-size prefixes","Validate producer output byte counts against expectations (checksums, size headers)","Keep producer and consumer Pkl versions aligned","Treat binary caches as disposable: on EOF, invalidate and re-generate"],"tags":["msgpack","decoding","eof","pkl-binary"],"backgroundTag":"unexpected-eof","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"}