{"record":{"id":"f7876b9eaa0eab9a","repo":"jestjs/jest","slug":"expected-color-expected-value-must-be-a-non-f7876b","errorCode":null,"errorMessage":"${EXPECTED_COLOR('expected')} value must be a non-negative integer","messagePattern":"(.+?) value must be a non-negative integer","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/jest-matcher-utils/src/index.ts","lineNumber":242,"sourceCode":"  options?: MatcherHintOptions,\n): void => {\n  ensureActualIsNumber(actual, matcherName, options);\n  ensureExpectedIsNumber(expected, matcherName, options);\n};\n\nexport const ensureExpectedIsNonNegativeInteger = (\n  expected: unknown,\n  matcherName: string,\n  options?: MatcherHintOptions,\n): void => {\n  if (\n    typeof expected !== 'number' ||\n    !Number.isSafeInteger(expected) ||\n    expected < 0\n  ) {\n    // Prepend maybe not only for backward compatibility.\n    const matcherString = (options ? '' : '[.not]') + matcherName;\n    throw new Error(\n      matcherErrorMessage(\n        matcherHint(matcherString, undefined, undefined, options),\n        `${EXPECTED_COLOR('expected')} value must be a non-negative integer`,\n        printWithType('Expected', expected, printExpected),\n      ),\n    );\n  }\n};\n\n// Given array of diffs, return concatenated string:\n// * include common substrings\n// * exclude change substrings which have opposite op\n// * include change substrings which have argument op\n//   with inverse highlight only if there is a common substring\nconst getCommonAndChangedSubstrings = (\n  diffs: Array<Diff>,\n  op: number,\n  hasCommonDiff: boolean,","sourceCodeStart":224,"sourceCodeEnd":260,"githubUrl":"https://github.com/jestjs/jest/blob/8e6d128e4a278059ecddecaa97400b04c8ae5fd9/packages/jest-matcher-utils/src/index.ts#L224-L260","documentation":"Thrown by ensureExpectedIsNonNegativeInteger in jest-matcher-utils. It guards matchers that take a positional index/count argument — notably haveBeenNthCalledWith and haveNthReturnedWith — requiring the expected argument to be a non-negative safe integer (no floats, no negatives, no strings).","triggerScenarios":"expect(fn).toHaveBeenNthCalledWith(-1, x); expect(fn).toHaveBeenNthCalledWith(1.5, x); expect(fn).toHaveNthReturnedWith('2', x); expect(fn).toHaveBeenNthCalledWith(NaN, x).","commonSituations":"Off-by-one in loop-driven assertions; passing a computed float index; reading an index from a string source; using 0 for nth when the matcher is 1-indexed (0 itself passes the guard but may misbehave in the matcher).","solutions":["Pass a non-negative integer (>=1 for nth-style matchers) literal or verified variable.","If the index is computed, guard it with Number.isInteger(n) && n >= 0 before the assertion.","Round or floor floats and parseInt string sources before passing."],"exampleFix":"// before\nexpect(fn).toHaveBeenNthCalledWith(i, payload);\n// after\nexpect(Number.isInteger(i) && i >= 1).toBe(true);\nexpect(fn).toHaveBeenNthCalledWith(i, payload);","handlingStrategy":"validation","validationCode":"if (!Number.isSafeInteger(nth) || nth < 0) {\n  throw new TypeError(`nth must be a non-negative integer, got ${nth}`);\n}\nexpect(fn).toHaveBeenNthCalledWith(nth, ...args);","typeGuard":"const isNonNegInt = (x: unknown): x is number =>\n  typeof x === 'number' && Number.isSafeInteger(x) && x >= 0;","tryCatchPattern":null,"preventionTips":["Treat nth-style indices as 1-based integers in test helpers.","Guard computed indices with Number.isInteger before assertion.","Avoid floats and stringified numbers as indices."],"tags":["matcher","type-validation","integer","spy"],"backgroundTag":null,"analyzedSha":"8e6d128e4a278059ecddecaa97400b04c8ae5fd9","analyzedAt":"2026-08-10T18:11:27.960Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}