{"record":{"id":"677c265b0d8db210","repo":"karatelabs/karate","slug":"array-index-too-large-for-dense-storage","errorCode":null,"errorMessage":"array index too large for dense storage: ","messagePattern":"array index too large for dense storage: ","errorType":"exception","errorClass":"JsErrorException","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/JsArray.java","lineNumber":216,"sourceCode":"     *  inspection paths that need slot identity. */\n    PropertySlot getOwnSlot(String name) {\n        return namedProps == null ? null : namedProps.get(name);\n    }\n\n    /** Spec CanonicalNumericIndexString check (§7.1.21 narrowed to integers).\n     *  Returns the integer value if {@code s} is a canonical integer-index\n     *  string (\"0\", \"1\", \"42\"), or {@code -1} otherwise. Package-private so\n     *  {@link JsObject#orderedOwnKeys} can apply §9.1.11.1 ordering. */\n    /** Largest hole-pad a single write may create. A sparse write like\n     *  {@code arr[2**30] = x} used to append a billion HOLEs and die with a\n     *  raw OutOfMemoryError; past this bound the write is refused with a JS\n     *  RangeError instead — loud, catchable, and it cannot take the JVM\n     *  down. True sparse storage is the deferred HOLE-elimination rework. */\n    static final int DENSE_PAD_LIMIT = 10_000_000;\n\n    void checkDensePad(long index) {\n        if (index - list.size() > DENSE_PAD_LIMIT) {\n            throw JsErrorException.rangeError(\n                    \"array index too large for dense storage: \" + index);\n        }\n    }\n\n    static int parseIndex(String s) {\n        // Strict canonical-integer parse: rejects \"01\", \"+1\", \"-1\", \"1.0\".\n        // Spec: an array index is a String whose value is a CanonicalNumericIndexString\n        // less than 2^32 - 1. The dense store is bounded by int, so indices\n        // beyond Integer.MAX_VALUE are treated as ordinary named properties —\n        // the long accumulator keeps a 10-digit index like \"4294967294\" from\n        // silently overflowing int into a negative value that a raw\n        // list.get() then crashes on (it used to surface as\n        // \"Index -2 out of bounds\", a Java leak).\n        int n = s.length();\n        if (n == 0) return -1;\n        if (n > 10) return -1; // any 11+ digit index exceeds 2^32-1 and isn't an array index\n        long v = 0;\n        for (int i = 0; i < n; i++) {","sourceCodeStart":198,"sourceCodeEnd":234,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/JsArray.java#L198-L234","documentation":"This RangeError guards the JsArray dense (ArrayList-backed) storage: assigning an index more than DENSE_PAD_LIMIT (10,000,000) beyond the current size would require padding millions of HOLE placeholders, risking JVM memory exhaustion. Karate throws instead of silently allocating, since true sparse storage is not implemented.","triggerScenarios":"arr[hugeIndex] = value where hugeIndex exceeds arr.length + 10,000,000 (e.g. arr[99999999] = 1 on a small array); also reachable via defineOwn/defineOwnAccessor and applySet paths.","commonSituations":"Using large sparse indices expecting JS-like sparse-array semantics; generating IDs or offsets as array indices (e.g. byte offsets, timestamps used as indices).","solutions":["Use a small, contiguous index range (keep max index within 10M of current length)","Use a plain JS object (or Java Map) as a sparse map instead of an array for large key spaces","Restructure data so large indices are not needed (e.g. store {index: value} pairs)"],"exampleFix":"// before\nvar arr = []; arr[50000000] = 'x'; // RangeError\n// after\nvar map = {}; map[50000000] = 'x';","handlingStrategy":"validation","validationCode":"function safeDenseAssign(arr, i, v) { if (i - arr.length > 10000000) throw new Error('index too large'); arr[i] = v; }","typeGuard":"function isWithinDenseLimit(arr, i) { return typeof i === 'number' && i >= 0 && i - arr.length <= 10000000; }","tryCatchPattern":"try { arr[hugeIndex] = v; } catch (e) { if (String(e).indexOf('dense storage') !== -1) { sparse[hugeIndex] = v; } else { throw e; } }","preventionTips":["Never use raw large numbers (offsets, IDs, timestamps) as array indices","Use objects/Maps for sparse key spaces","Keep array indices contiguous and small"],"tags":["javascript","array","range-error","memory"],"backgroundTag":"index-out-of-range","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-16T19:17:19.609Z"}