angular/components · error
Index must not be negative
Error message
Index must not be negative
What it means
Thrown by ComponentHarnessEnvironment.getHarnessAtIndex when the caller passes a negative offset. The method indexes into the array of matched harnesses, and a negative index has no meaning there, so the library rejects it up-front before performing any locator queries.
Source
Thrown at src/cdk/testing/harness-environment.ts:266
return this.locatorForOptional(query)();
}
/**
* Searches for an instance of the component corresponding to the given harness type and index
* under the `HarnessEnvironment`'s root element, and returns a `ComponentHarness` for that
* instance. The index specifies the offset of the component to find. If no matching
* component is found at that index, an error is thrown.
* @param query A query for a harness to create
* @param index The zero-indexed offset of the component to find
* @return An instance of the given harness type
* @throws If a matching component instance can't be found.
*/
async getHarnessAtIndex<T extends ComponentHarness>(
query: HarnessQuery<T>,
offset: number,
): Promise<T> {
if (offset < 0) {
throw Error('Index must not be negative');
}
const harnesses = await this.locatorForAll(query)();
if (offset >= harnesses.length) {
throw Error(`No harness was located at index ${offset}`);
}
return harnesses[offset];
}
/**
* Searches for all instances of the component corresponding to the given harness type under the
* `HarnessEnvironment`'s root element, and returns a list `ComponentHarness` for each instance.
* @param query A query for a harness to create
* @return A list instances of the given harness type.
*/
getAllHarnesses<T extends ComponentHarness>(query: HarnessQuery<T>): Promise<T[]> {
return this.locatorForAll(query)();
}
View on GitHub (pinned to 0411926e7d)
Solutions
- Pass a non-negative, in-range offset; check it is >= 0 before calling.
- Use locatorForAll/queryAll and index the returned array yourself with bounds checking.
- If looking for the last harness, use harnesses[harnesses.length - 1] on results from getHarnesses, not a computed negative value.
Example fix
// before
const harness = await env.getHarnessAtIndex(MyHarness, selectedIndex);
// after
if (selectedIndex < 0) throw new Error('Nothing selected');
const harness = await env.getHarnessAtIndex(MyHarness, selectedIndex); Defensive patterns
Strategy: validation
Validate before calling
if (!Number.isInteger(offset) || offset < 0) throw new RangeError(`offset must be >= 0, got ${offset}`); Type guard
const isValidOffset = (n: unknown): n is number => typeof n === 'number' && Number.isInteger(n) && n >= 0;
Try / catch
try { return await env.getHarnessAtIndex(MyHarness, offset); } catch (e) { if ((e as Error).message.includes('Index must not be negative')) return null; throw e; } Prevention
- Clamp/validate indices from external state before indexing harnesses
- Prefer getAllHarnesses plus explicit length checks over index-based access
When it happens
Trigger: Calling getHarnessAtIndex(query, offset) with offset < 0, typically from a loop that computes the index dynamically (e.g. counter starting at -1, or index derived from an empty/decremented variable).
Common situations: Loop variables initialized wrong, off-by-one logic when picking 'the last but one' harness (index length-2 on small lists), or binding an index from user/model state that can be -1 (e.g. selectedIndex of an empty list).
Related errors
- CDK Component harness query must contain at least one elemen
- No harness was located at index ${offset}
- Failed to find element matching one of the following queries
- Unable to retrieve options for autocomplete. Autocomplete pa
- Unable to retrieve option groups for autocomplete. Autocompl
AI-assisted analysis of angular/components@0411926e7d (2026-08-31).
Data as JSON: /api/errors/7e52f7597f483b3a.
Report an issue: GitHub.