antlr/antlr4 · error · RangeError

index cannot be negative

Error message

index cannot be negative

What it means

The companion check in setDelimiters for the stop delimiter: it must be non-null and non-empty because the scanner needs a concrete terminator to find each tag's end. An empty stop would make indexOf return immediately-adjacent positions and break tag boundary detection, so the method rejects it with IllegalArgumentException.

Source

Thrown at runtime/JavaScript/src/antlr4/misc/BitSet.js:110

    get length() {
        return this.data.map(l => BitSet._bitCount(l)).reduce((s, v) => s + v, 0);
    }

    _resize(index) {
        const count = index + 32 >>> 5;
        if (count <= this.data.length) {
            return;
        }
        const data = new Uint32Array(count);
        data.set(this.data);
        data.fill(0, this.data.length);
        this.data = data;
    }

    static _checkIndex(index) {
        if (index < 0)
            throw new RangeError("index cannot be negative");
    }

    static _bitCount(l) {
        // see https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
        let count = 0;
        l = l - ((l >> 1) & 0x55555555);
        l = (l & 0x33333333) + ((l >> 2) & 0x33333333);
        l = (l + (l >> 4)) & 0x0f0f0f0f;
        l = l + (l >> 8);
        l = l + (l >> 16);
        return count + l & 0x3f;
    }
}

View on GitHub (pinned to 7d5770395b)

Solutions

  1. Pass a valid stop delimiter: setDelimiters("{", "}", "\\").
  2. Assert both delimiters are non-empty when loading them from configuration.
  3. Unit-test the delimiter configuration separately from pattern compilation.

Example fix

// before
matcher.setDelimiters("{", cfg.get("stop"), "\\"); // empty string -> IllegalArgumentException

// after
String stop = cfg.get("stop");
if (stop == null || stop.isEmpty()) throw new ConfigException("pattern stop delimiter missing");
matcher.setDelimiters("{", stop, "\\");
Defensive patterns

Strategy: validation

Validate before calling

if (stop == null || stop.isEmpty()) throw new ConfigException("stop delimiter required");
matcher.setDelimiters(start, stop, escape);

Type guard

boolean isValidDelimiter(String d) { return d != null && !d.isEmpty(); }

Prevention

When it happens

Trigger: Calling setDelimiters("{", "", ...) or with a null stop when configuring custom pattern tag syntax.

Common situations: Same custom-delimiter scenario as the start check; typically a typo, a constants class returning empty string, or reading delimiters from a properties file where the stop key is missing.

Related errors


AI-assisted analysis of antlr/antlr4@7d5770395b (2026-08-14). Data as JSON: /api/errors/a1edf007a56271f3. Report an issue: GitHub.