{"record":{"id":"7e52f7597f483b3a","repo":"angular/components","slug":"index-must-not-be-negative","errorCode":null,"errorMessage":"Index must not be negative","messagePattern":"Index must not be negative","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cdk/testing/harness-environment.ts","lineNumber":266,"sourceCode":"    return this.locatorForOptional(query)();\n  }\n\n  /**\n   * Searches for an instance of the component corresponding to the given harness type and index\n   * under the `HarnessEnvironment`'s root element, and returns a `ComponentHarness` for that\n   * instance. The index specifies the offset of the component to find. If no matching\n   * component is found at that index, an error is thrown.\n   * @param query A query for a harness to create\n   * @param index The zero-indexed offset of the component to find\n   * @return An instance of the given harness type\n   * @throws If a matching component instance can't be found.\n   */\n  async getHarnessAtIndex<T extends ComponentHarness>(\n    query: HarnessQuery<T>,\n    offset: number,\n  ): Promise<T> {\n    if (offset < 0) {\n      throw Error('Index must not be negative');\n    }\n    const harnesses = await this.locatorForAll(query)();\n    if (offset >= harnesses.length) {\n      throw Error(`No harness was located at index ${offset}`);\n    }\n    return harnesses[offset];\n  }\n\n  /**\n   * Searches for all instances of the component corresponding to the given harness type under the\n   * `HarnessEnvironment`'s root element, and returns a list `ComponentHarness` for each instance.\n   * @param query A query for a harness to create\n   * @return A list instances of the given harness type.\n   */\n  getAllHarnesses<T extends ComponentHarness>(query: HarnessQuery<T>): Promise<T[]> {\n    return this.locatorForAll(query)();\n  }\n","sourceCodeStart":248,"sourceCodeEnd":284,"githubUrl":"https://github.com/angular/components/blob/0411926e7d8ae06b32236ec1048a888cfad5abf2/src/cdk/testing/harness-environment.ts#L248-L284","documentation":"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.","triggerScenarios":"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).","commonSituations":"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).","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."],"exampleFix":"// before\nconst harness = await env.getHarnessAtIndex(MyHarness, selectedIndex);\n// after\nif (selectedIndex < 0) throw new Error('Nothing selected');\nconst harness = await env.getHarnessAtIndex(MyHarness, selectedIndex);","handlingStrategy":"validation","validationCode":"if (!Number.isInteger(offset) || offset < 0) throw new RangeError(`offset must be >= 0, got ${offset}`);","typeGuard":"const isValidOffset = (n: unknown): n is number => typeof n === 'number' && Number.isInteger(n) && n >= 0;","tryCatchPattern":"try { return await env.getHarnessAtIndex(MyHarness, offset); } catch (e) { if ((e as Error).message.includes('Index must not be negative')) return null; throw e; }","preventionTips":["Clamp/validate indices from external state before indexing harnesses","Prefer getAllHarnesses plus explicit length checks over index-based access"],"tags":["angular-cdk","testing","component-harness","argument-validation"],"backgroundTag":"negative-index-argument","analyzedSha":"0411926e7d8ae06b32236ec1048a888cfad5abf2","analyzedAt":"2026-08-31T11:58:23.400Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}