karatelabs/karate · error · RangeError
Set-like object's size is negative
Error message
Set-like object's size is negative
What it means
SetRecord validation per the ES spec (ToIntegerOrInfinity then RangeError): a Set-like object's 'size' coerced to a negative number, which is invalid for set operations. Fix the object so its 'size' is a non-negative number.
Solutions
- Fix the size computation so it is non-negative, or clamp: Math.max(0, size).
- Use a real Set as the other argument.
- Validate other.size >= 0 before calling.
Example fix
// before
const like = { size: computedSize, has, keys };
mySet.difference(like);
// after
const like = { size: Math.max(0, computedSize), has, keys };
mySet.difference(like); Defensive patterns
Strategy: validation
Validate before calling
if (Number(other?.size) < 0) throw new RangeError('size must be >= 0'); Type guard
function hasNonNegativeSize(v) { return v !== null && typeof v === 'object' && Number.isFinite(Number(v.size)) && Number(v.size) >= 0; } Try / catch
try { return mySet.difference(other); } catch (e) { if (String(e).includes('size is negative')) return mySet.difference(new Set()); throw e; } Prevention
- Clamp computed sizes with Math.max(0, size).
- Fix off-by-one or subtraction bugs in size getters.
- Add assertions that size >= 0 when building Set-likes.
When it happens
Trigger: set.difference({ size: -1, has: fn, keys: fn }); or a Set-like whose size getter computes a negative count.
Common situations: Custom Set-like wrappers computing size with an off-by-one or subtracting counts incorrectly; deserialized objects with negative size sentinels.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- array index too large for dense storage:
- Cannot convert non-finite number to BigInt
- Cannot convert non-integer number to BigInt
- Constructor Set requires 'new'
- Invalid array length
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/c6673298eba8bb4b.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/JsSetPrototype.java:177
if (!(other instanceof ObjectLike obj)) {
throw JsErrorException.typeError("Set.prototype method called with non-object");
}
CoreContext cc = context instanceof CoreContext c ? c : null;
Object rawSize = obj.getMember("size", obj, cc);
Number numSize = Terms.toNumberCoerce(rawSize, cc);
double d = numSize.doubleValue();
if (Double.isNaN(d)) {
throw JsErrorException.typeError("Set-like object's size is not a number");
}
// ToIntegerOrInfinity, then RangeError on negative — spec step 7.
long intSize;
if (Double.isInfinite(d)) {
intSize = d > 0 ? Long.MAX_VALUE : Long.MIN_VALUE;
} else {
intSize = (long) d;
}
if (intSize < 0) {
throw JsErrorException.rangeError("Set-like object's size is negative");
}
Object hasFn = obj.getMember("has", obj, cc);
if (!(hasFn instanceof JsCallable has)) {
throw JsErrorException.typeError("Set-like object's 'has' is not callable");
}
Object keysFn = obj.getMember("keys", obj, cc);
if (!(keysFn instanceof JsCallable keys)) {
throw JsErrorException.typeError("Set-like object's 'keys' is not callable");
}
return new SetRecord(obj, intSize, has, keys);
}
private static JsIterator keysIter(SetRecord rec, Context ctx) {
return IterUtils.iteratorFromCallable(rec.keys, rec.setObj, ctx);
}
/** Spec normalize: -0 → +0 on values pulled from a foreign keys() iteration. */
private static Object normalize(Object v) {View on GitHub (pinned to a22eb90246)