apple/pkl · error · UncheckedIOException

IO exception during decoding

Error message

IO exception during decoding

What it means

The public next() of the decoder's element iterator wraps any IOException from getNext() via doIOFail, producing a failure whose message is "IO exception during decoding" (with the underlying cause attached). It surfaces I/O problems (e.g. reading from an underlying stream/channel) that occur while decoding the element at the current path.

Solutions

  1. Inspect the cause attached by doIOFail to find the real I/O problem (closed stream, permission, disk error) and fix that.
  2. Ensure the InputStream/channel remains open for the whole decoding session; don't close it before iteration completes.
  3. If reading over an unreliable transport, read the full payload into memory (or a local file) first, then decode from the stable buffer.
  4. Add retry with backoff around the I/O acquisition step if the source is a remote, transiently-failing resource.

Example fix

// before: stream closed too early
try (InputStream in = open()) {
  iterator = decoder.decode(in).elements();
}
for (T v : iterator) { ... } // IOException during decoding
// after: keep stream open during iteration
try (InputStream in = open()) {
  for (T v : decoder.decode(in).elements()) { ... }
}
Defensive patterns

Strategy: try-catch

Try / catch

try (InputStream in = openSource()) {
  for (Iterator<T> it = decoder.decode(in).elements(); ; ) {
    try {
      T value = it.next();
      consume(value);
    } catch (IOException e) {
      throw new SourceReadException("IO exception during decoding", e); // inspect cause
    }
  }
}

Prevention

When it happens

Trigger: Iterating members/elements of a decoded container (member -> next) when the underlying input source (file channel, InputStream) throws IOException mid-decode: disk read failure, closed stream, socket reset while streaming the binary data.

Common situations: Decoding directly from a network stream that drops mid-read; reading from a file on a failing/unmounted disk; a stream closed by another thread or by try-with-resources before iteration finishes.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


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

Appendix: source

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

    DecodeIterator(int size) {
      this.size = size;
    }

    public int getSize() {
      return size;
    }

    public boolean hasNext() {
      return idx < size;
    }

    public T next() {
      currPath.push(idx);
      try {
        return getNext();
      } catch (IOException e) {
        throw doIOFail(e);
      } finally {
        currPath.pop();
        idx++;
      }
    }

    abstract T getNext() throws IOException;
  }

  protected class ObjectDecodeIterator extends DecodeIterator<DecodedObjectMember> {
    ObjectDecodeIterator(int size) {
      super(size);
      checkCollectionLength(size, "object");
    }

    @Override
    DecodedObjectMember getNext() throws IOException {
      var memberLen = unpacker.unpackArrayHeader();

View on GitHub (pinned to f3efcbfc9b)