jestjs/jest · error · Error
expected value must be a non-negative integer
Error message
expected value must be a non-negative integer
What it means
Thrown by ensureExpectedIsNonNegativeInteger when the expected value fails any of: typeof !== 'number', Number.isSafeInteger is false, or value < 0. This guard backs matchers whose expected argument is a count or an index — notably toHaveBeenCalledTimes and the n in toHaveBeenCalledNth / toHaveBeenNthCalledWith. Note it deliberately rejects bigint (the check is typeof === 'number' only), negative numbers, NaN, and non-safe integers.
Source
Thrown at packages/jest-matcher-utils/src/index.ts:242
options?: MatcherHintOptions,
): void => {
ensureActualIsNumber(actual, matcherName, options);
ensureExpectedIsNumber(expected, matcherName, options);
};
export const ensureExpectedIsNonNegativeInteger = (
expected: unknown,
matcherName: string,
options?: MatcherHintOptions,
): void => {
if (
typeof expected !== 'number' ||
!Number.isSafeInteger(expected) ||
expected < 0
) {
// Prepend maybe not only for backward compatibility.
const matcherString = (options ? '' : '[.not]') + matcherName;
throw new Error(
matcherErrorMessage(
matcherHint(matcherString, undefined, undefined, options),
`${EXPECTED_COLOR('expected')} value must be a non-negative integer`,
printWithType('Expected', expected, printExpected),
),
);
}
};
// Given array of diffs, return concatenated string:
// * include common substrings
// * exclude change substrings which have opposite op
// * include change substrings which have argument op
// with inverse highlight only if there is a common substring
const getCommonAndChangedSubstrings = (
diffs: Array<Diff>,
op: number,
hasCommonDiff: boolean,View on GitHub (pinned to f49721c78e)
Solutions
- Use a non-negative integer literal or compute one with Math.floor/Math.trunc: expect(fn).toHaveBeenCalledTimes(Math.floor(total / step)).
- Verify the count expression with a log before the assertion; fix NaN/undefined sources upstream.
- Remember indices are 1-based for nth matchers — pass 1 for the first call, not 0.
- Do not pass a bigint count; convert with Number() if a bigint source is involved and it fits in a safe integer.
Example fix
// before expect(handler).toHaveBeenCalledTimes(events.length / 2); // 2.5 when length is 5 // after expect(handler).toHaveBeenCalledTimes(Math.floor(events.length / 2));
Defensive patterns
Strategy: validation
Validate before calling
function assertCount(n: unknown): asserts n is number {
if (typeof n !== 'number' || !Number.isSafeInteger(n) || n < 0) {
throw new Error(`expected call count must be a non-negative integer, got ${n}`);
}
}
const expected = Math.floor(events.length / 2);
assertCount(expected);
expect(fn).toHaveBeenCalledTimes(expected); Type guard
const isNonNegInt = (v: unknown): v is number => typeof v === 'number' && Number.isSafeInteger(v) && v >= 0; const expected = isNonNegInt(raw) ? raw : Math.max(0, Math.floor(Number(raw) || 0)); expect(fn).toHaveBeenCalledTimes(expected);
Prevention
- Use Math.floor/Math.trunc on any computed count.
- Remember nth-style matchers are 1-indexed.
- Never pass a bigint as a call count.
When it happens
Trigger: expect(fn).toHaveBeenCalledTimes(-1); expect(fn).toHaveBeenCalledTimes(2.5); expect(fn).toHaveBeenCalledTimes('3'); expect(fn).toHaveBeenCalledTimes(NaN); expect(fn).toHaveBeenCalledTimes(2n); expect(fn).toHaveBeenNthCalledWith(0, ...) (zero-based thinking — n must be >=1).
Common situations: Off-by-one confusion between array length and call index; computing the expected count from a float division (arr.length / 2 when length is odd); a dynamically computed count that yields NaN because of an undefined input; assuming bigint works like number for counts.
Related errors
- received value must be a number or bigint
- expected value must be a number or bigint
- @jest/diff-sequences: ${name} typeof ${typeof arg} is not a
- @jest/diff-sequences: ${name} typeof ${type} is not a functi
- any() expects to be passed a constructor function. Please pa
AI-assisted analysis of jestjs/jest@f49721c78e (2026-08-03).
Data as JSON: /data/errors/b9ba1fc8fe4178a0.json.
Report an issue: GitHub.