karatelabs/karate · error · JsErrorException (typeError)
get by index [ ] for non-array
Error message
get by index [${i}] for non-array: ${object} What it means
Thrown by Karate's `get by index` path when an index-style access is applied to a value that is neither a JsArray/List nor a Map/ObjectLike — e.g. a string, number, or boolean. Arrays and maps support `[i]` lookups; anything else has no indexed value, so the engine raises a TypeError naming the offending value.
Solutions
- Verify the actual type of the value (print it or match it against `#array`/`#object`/`#string`) before indexing.
- Fix the JSON path or expression so it selects the collection, not a leaf.
- Convert/unwrap the value first if it is a single object that should be a one-element list (e.g. `* def list = karate.sizeOf(x) != null ? x : [x]`).
- Use schema matching (`match each`, `##[] array`) to catch shape drift early.
Example fix
// before (name is a string) * match response.name[0] == 'x' // after * match response.name == 'x' // or if it can be either: * match response.name == '#(karate.sizeOf(response.name) != null ? response.name[0] : response.name)'
Defensive patterns
Strategy: validation
Validate before calling
* match response.field == '#array' // or '#object' / '#string' before indexing
Type guard
function canIndex(v) { return v instanceof Array || (v && typeof v === 'object'); } Prevention
- Assert payload shapes with Karate fuzzy markers before indexed access.
- Never index fields you haven't typed; print suspicious values during debugging.
- Handle API responses that return a single object instead of an array.
- Keep JSON schema definitions next to the feature and validate early.
When it happens
Trigger: Expressions like `response[0]` where `response` is a scalar/string, or `get by index` on a non-collection JSON value; also `karate.get('x[0]')` style access where `x` resolved to a primitive.
Common situations: Assuming an API field is an array when it is a string or object, indexing a JSON path result that pointed at a leaf value, schema drift between expected and actual payload shapes (array vs single object).
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- cannot read properties of
- toBytes() argument must be a list of numbers, got
- toBytes() list must contain only numbers, got
- xmlPath() first argument must be XML node or string, but was
- Array.from requires an iterable or array-like object, not
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/f128e95fc3d9e876.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/PropertyAccess.java:912
// never see the sentinel.
return JsArray.unwrapHole(list.get(i));
}
if (object instanceof String s) {
if (i < 0 || i >= s.length()) return Terms.UNDEFINED;
return s.substring(i, i + 1);
}
if (object instanceof byte[] bytes) {
if (i < 0 || i >= bytes.length) return Terms.UNDEFINED;
return bytes[i] & 0xFF;
}
ObjectLike converted = Terms.toObjectLike(object);
if (converted instanceof JsArray jsArray) {
return jsArray.getIndexedValue(i, jsArray, context);
}
if (object instanceof Map || object instanceof ObjectLike) {
return getByName(object, Terms.toPropertyKey(index), optional, context, functionCall);
}
throw JsErrorException.typeError("get by index [" + i + "] for non-array: " + object);
}
return getByName(object, Terms.toPropertyKey(index), optional, context, functionCall);
}
private static Object getByName(Object object, String name, boolean optional,
CoreContext context, boolean functionCall) {
return getByName(object, name, optional, context, functionCall, object);
}
/** Receiver-aware variant for super references (§13.3.7.3): the lookup
* walks {@code object}'s chain, but any getter runs with {@code receiver}
* as its {@code this}. All non-super callers pass {@code object} itself
* via the delegating overload above. */
private static Object getByName(Object object, String name, boolean optional,
CoreContext context, boolean functionCall, Object receiver) {
if (object == null || object == Terms.UNDEFINED) {
// Reading a property of null/undefined is a TypeError (or undefined under ?.).
// Do NOT fall back to a same-named scope variable: `a.b.c` where `a.b` is nullView on GitHub (pinned to a22eb90246)