apple/pkl · error

elementIndexOutOfRange

elementIndexOutOfRange

Error message

elementIndexOutOfRange

What it means

Pkl's List.slice(start, exclusiveEnd) validates the start index before slicing. If start is negative or greater than the list length, the runtime throws elementIndexOutOfRange with the valid range [0, length]. The collection itself is attached as program value 'Collection' for debugging.

Source

Thrown at pkl-core/src/main/java/org/pkl/core/stdlib/base/ListNodes.java:87

      return self.getLastIndex();
    }
  }

  public abstract static class getOrNull extends ExternalMethod1Node {
    @Specialization
    protected Object eval(VmList self, long index) {
      return self.getOrNull(index);
    }
  }

  public abstract static class sublist extends ExternalMethod2Node {
    @Specialization
    protected Object eval(VmList self, long start, long exclusiveEnd) {
      var length = self.getLength();

      if (start < 0 || start > length) {
        CompilerDirectives.transferToInterpreter();
        throw exceptionBuilder()
            .evalError("elementIndexOutOfRange", start, 0, length)
            .withProgramValue("Collection", self)
            .build();
      }
      if (exclusiveEnd < start || exclusiveEnd > length) {
        CompilerDirectives.transferToInterpreter();
        throw exceptionBuilder()
            .evalError("elementIndexOutOfRange", exclusiveEnd, start, length)
            .withProgramValue("Collection", self)
            .build();
      }
      return self.subList(start, exclusiveEnd);
    }
  }

  public abstract static class sublistOrNull extends ExternalMethod2Node {
    @Specialization
    protected Object eval(VmList self, long start, long exclusiveEnd) {

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Verify the start index is within 0..list.length before calling slice
  2. Clamp the start index: Math.max(0, Math.min(start, list.length))
  3. Check the upstream computation that produced the index (off-by-one, wrong list length)
  4. Print/inspect list.length to confirm the expected size

Example fix

// before
local start = items.length - extra  // extra > items.length -> negative
items.slice(start, items.length)
// after
local start = Math.max(0, items.length - extra)
items.slice(start, items.length)
Defensive patterns

Strategy: validation

Validate before calling

if (start < 0 || start > list.length) throw new Error("slice start "+start+" out of [0, "+list.length+"]")

Type guard

function isValidStart(list, start) { return typeof start === "number" && start >= 0 && start <= list.length; }

Prevention

When it happens

Trigger: Calling List.slice() with a negative start (e.g. slice(-1, 3)) or a start beyond the list length (e.g. slice(5, 6) on a 3-element list). Start == length is allowed (yields empty list) but start > length is not.

Common situations: Computing slice bounds from dynamic values such as page sizes, offsets derived from external config, or lengths of other collections that may be shorter than expected.

Related errors


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