vitest-dev/vitest · error · TypeError

[vitest] Redirect mocks require a redirect string.

Error message

[vitest] Redirect mocks require a redirect string.

What it means

Thrown by MockRegistry.register when a mock of type 'redirect' is registered but factoryOrRedirect is not a string. Redirect mocks point one module at another module path, so the target must be a string path. This guard rejects functions, objects, or undefined for the redirect branch.

Example fix

// before
registry.register({ type: 'redirect', raw: 'a', id: 'a', url: 'a' }, () => 'b')
// after
registry.register({ type: 'redirect', raw: 'a', id: 'a', url: 'a' }, 'b')
Defensive patterns

Strategy: validation

Validate before calling

// Validate redirect target is a string path before registering
if (typeof target !== 'string' || !target.trim()) {
  throw new Error('redirect target must be a non-empty module path string')
}
registry.register({ type: 'redirect', raw, id, url }, target)

Type guard

function isRedirectTarget(v: unknown): v is string { return typeof v === 'string' && v.length > 0 }

Prevention

When it happens

Trigger: Calling vi.mock('a', () => import('b')) when the system expects a redirect string; or registry.register({ type: 'redirect', ... }, nonString). Also when vi.mock's second argument is a factory but the internal type was resolved as redirect.

Common situations: Mixing up the redirect API (which takes a module path string) with the manual factory API (which takes a function); passing an object or undefined where a redirect path string is required; misconfigured mock redirection tooling.

Related errors


AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11). Data as JSON: /api/errors/2bd62ecf300cc23f. Report an issue: GitHub.

Appendix: source

Thrown at packages/mocker/src/registry.ts:123

    if (type === 'manual') {
      if (typeof factoryOrRedirect !== 'function') {
        throw new TypeError('[vitest] Manual mocks require a factory function.')
      }
      const mock = new ManualMockedModule(raw, id, url, factoryOrRedirect)
      this.add(mock)
      return mock
    }
    else if (type === 'automock' || type === 'autospy') {
      const mock = type === 'automock'
        ? new AutomockedModule(raw, id, url)
        : new AutospiedModule(raw, id, url)
      this.add(mock)
      return mock
    }
    else if (type === 'redirect') {
      if (typeof factoryOrRedirect !== 'string') {
        throw new TypeError('[vitest] Redirect mocks require a redirect string.')
      }
      const mock = new RedirectedModule(raw, id, url, factoryOrRedirect)
      this.add(mock)
      return mock
    }
    else {
      throw new Error(`[vitest] Unknown mock type: ${type}`)
    }
  }

  public delete(id: string): void {
    this.registryByUrl.delete(id)
  }

  public deleteById(id: string): void {
    this.registryById.delete(id)
  }

View on GitHub (pinned to 1fa9837ec2)