apple/pkl · error
elementIndexOutOfRange
elementIndexOutOfRange
Error message
elementIndexOutOfRange ${index} 0 ${max} What it means
Indexing a List with `[i]` outside the valid range 0..length-1 throws `elementIndexOutOfRange`, displaying the requested index and the maximum valid index. Pkl lists are fixed-size, so there is no auto-growth or negative wraparound.
Source
Thrown at pkl-core/src/main/java/org/pkl/core/ast/expression/binary/SubscriptNode.java:63
"charIndexOutOfRange", index, 0, receiver.codePointCount(0, receiver.length()) - 1)
.withSourceSection(getRightNode().getSourceSection())
.withProgramValue("String", receiver)
.build();
}
if (Character.isHighSurrogate(receiver.charAt(charIndex))
&& charIndex < receiver.length() - 1
&& Character.isLowSurrogate(receiver.charAt(charIndex + 1))) {
return receiver.substring(charIndex, charIndex + 2);
}
return receiver.substring(charIndex, charIndex + 1);
}
@Specialization
protected Object eval(VmList receiver, long index) {
if (index < 0 || index >= receiver.getLength()) {
CompilerDirectives.transferToInterpreter();
throw exceptionBuilder()
.evalError("elementIndexOutOfRange", index, 0, receiver.getLength() - 1)
.withProgramValue("Collection", receiver)
.build();
}
return receiver.get(index);
}
@Specialization
protected Object eval(VmMap receiver, Object key) {
var result = receiver.getOrNull(key);
if (result != null) return result;
CompilerDirectives.transferToInterpreter();
throw exceptionBuilder().cannotFindKey(receiver, key).build();
}
@Specialization
protected Object eval(View on GitHub (pinned to f3efcbfc9b)
Solutions
- Validate `index >= 0 && index < list.length` before subscripting
- Use `list.elementAtOrNull(index)` if available, or guard with `list.isEmpty()`
- Fix the index computation (length vs length-1)
Example fix
// before (Pkl) val last = items[items.length] // after val last = items[items.length - 1]
Defensive patterns
Strategy: validation
Validate before calling
function safeListGet(list, i) {
return Array.isArray(list) && Number.isInteger(i) && i >= 0 && i < list.length ? list[i] : null;
} Type guard
const inListBounds = (list, i) => Array.isArray(list) && i >= 0 && i < list.length;
Prevention
- Use length - 1 for last element, not length
- Check non-emptiness before positional access
- Validate externally-supplied indices against list length
When it happens
Trigger: `list[index]` with index < 0 or index >= list.length, e.g. `servers[servers.length]` (off-by-one) on an empty or short list.
Common situations: Off-by-one in loops, assuming a list is non-empty, or deriving indices from external config that doesn't match list size.
Related errors
- elementIndexOutOfRange
- charIndexOutOfRange
- elementIndexOutOfRange
- elementIndexOutOfRange
- type mismatch: value is not of type List
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/942755736ba33190.
Report an issue: GitHub.