karatelabs/karate · error · IndexOutOfBoundsException

index: , size

Error message

index: ${index}, size: ${size}

What it means

Bounds check in DiskBackedList.get(): the requested index is outside the valid range [0, size), where size is the number of items backed by the on-disk store. Fires on negative or >= size indexes; standard IndexOutOfBoundsException, not a storage failure.

Solutions

  1. Clamp indexes: only call get(i) for 0 <= i < list.size()
  2. Re-read size() immediately before indexed access instead of caching it
  3. Use the iterator or for-each loop instead of manual index arithmetic
  4. Synchronize access if the list is mutated concurrently

Example fix

// before
for (int i = 0; i < cachedSize; i++) use(list.get(i));
// after
for (int i = 0; i < list.size(); i++) use(list.get(i));
Defensive patterns

Strategy: validation

Validate before calling

if (index < 0 || index >= list.size()) throw new IndexOutOfBoundsException("index: " + index + ", size: " + list.size());

Type guard

boolean inRange(int i, List<?> l) { return i >= 0 && i < l.size(); }

Try / catch

try { return list.get(i); } catch (IndexOutOfBoundsException e) { log.warn("bad index {} vs size {}", i, list.size()); return null; }

Prevention

When it happens

Trigger: Calling get() with an index from a stale size snapshot while the list was cleared or truncated; arithmetic errors producing negative indexes; concurrent modification where one thread removes items while another indexes.

Common situations: Loop conditions using a cached size; off-by-one in pagination code; iterating with manual index math instead of the iterator.

Related errors


AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12). Data as JSON: /api/errors/db2f38f4b8f76e7a. Report an issue: GitHub.

Appendix: source

Thrown at karate-core/src/main/java/io/karatelabs/match/DiskBackedList.java:182

    private static Object deserializeItem(String json) {
        if (json == null || json.isEmpty() || "null".equals(json)) {
            return null;
        }
        return JSONValue.parse(json);
    }

    @Override
    public int size() {
        return size;
    }

    @Override
    public Object get(int index) {
        if (closed) {
            throw new IllegalStateException("store has been closed");
        }
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException("index: " + index + ", size: " + size);
        }
        try {
            if (raf == null) {
                raf = new RandomAccessFile(tempFile, "r");
            }
            long offset = lineOffsets.get(index);
            raf.seek(offset);
            String line = raf.readLine();
            return deserializeItem(line);
        } catch (IOException e) {
            throw new RuntimeException("failed to read item at index " + index, e);
        }
    }

    @Override
    public Iterator<Object> iterator() {
        if (closed) {
            throw new IllegalStateException("store has been closed");

View on GitHub (pinned to a22eb90246)