remix-run/remix · error · AssertionError

${matcherName} requires a mock function with a .mock.calls p

Error message

${matcherName} requires a mock function with a .mock.calls property

What it means

The `--step` option must be a positive integer (1, 2, 3, ...). `parseStepOption` converts the string with `Number()` and rejects anything that is not an integer >= 1 — zero, negatives, decimals, NaN, or empty strings.

Source

Thrown at packages/assert/src/lib/expect.ts:84

interface MockShape {
  mock: {
    calls: Array<{ arguments: unknown[] }>
  }
}

function isMockFn(value: unknown): value is MockShape {
  return (
    typeof value === 'function' &&
    typeof (value as any).mock === 'object' &&
    (value as any).mock != null &&
    Array.isArray((value as any).mock.calls)
  )
}

function getMockCalls(received: unknown, matcherName: string): Array<{ arguments: unknown[] }> {
  if (!isMockFn(received)) {
    throw new AssertionError({
      message: `${matcherName} requires a mock function with a .mock.calls property`,
      operator: matcherName,
    })
  }
  return received.mock.calls
}

function checkErrorMatch(error: any, expected: unknown): boolean {
  if (expected === undefined) return true
  if (typeof expected === 'function') {
    if (expected.prototype != null && expected.prototype instanceof Error) {
      return error instanceof (expected as new (...args: any[]) => Error)
    }
    return Boolean((expected as (e: unknown) => unknown)(error))
  }
  if (expected instanceof Error) {
    return error?.message === expected.message
  }

View on GitHub (pinned to 9696913134)

Solutions

  1. Use a positive whole number: `--step 3`
  2. Guard scripted values (e.g. `[ "$step" -ge 1 ]`) before invoking the CLI
  3. Omit `--step` to use the default behavior

Example fix

# before
remix db rollback --step 0
# after
remix db rollback --step 1
Defensive patterns

Strategy: validation

Validate before calling

let step = Number(process.env.DB_STEP ?? 1);
if (!Number.isInteger(step) || step < 1) step = 1;
run(['remix','db','rollback','--step',String(step)])

Type guard

function isValidStep(v: string): boolean {
  let n = Number(v);
  return v.trim() !== '' && Number.isInteger(n) && n >= 1;
}

Prevention

When it happens

Trigger: Passing `--step 0`, `--step -1`, `--step 1.5`, `--step abc`, or `--step ""` to a db command accepting `--step`; `Number(value)` yields NaN or fails the integer/positivity checks.

Common situations: Scripts computing step counts dynamically that produce 0 or empty values; copy-pasting from docs; passing decimals expecting partial steps.

Understand the failure class

Background: Invalid option value errors: "must be one of", "is not a valid", and "only allows" failures explained — this error's family across 23 libraries.

Related errors


AI-assisted analysis of remix-run/remix@9696913134 (2026-08-27). Data as JSON: /api/errors/0ef5ec45c0492cea. Report an issue: GitHub.