vuejs/vue-router · warning

invalid redirect option: ${JSON.stringify(redirect)}

Error message

invalid redirect option: ${JSON.stringify(redirect)}

What it means

vue-router emits this dev-mode warning when a route's `redirect` option is neither a string, an object with a `path`/`name`, nor a function. The matcher cannot build a redirect target from it, so it warns and falls back to creating an empty/non-matching route for the location.

Source

Thrown at src/create-matcher.js:112

    return _createRoute(null, location)
  }

  function redirect (
    record: RouteRecord,
    location: Location
  ): Route {
    const originalRedirect = record.redirect
    let redirect = typeof originalRedirect === 'function'
      ? originalRedirect(createRoute(record, location, null, router))
      : originalRedirect

    if (typeof redirect === 'string') {
      redirect = { path: redirect }
    }

    if (!redirect || typeof redirect !== 'object') {
      if (process.env.NODE_ENV !== 'production') {
        warn(
          false, `invalid redirect option: ${JSON.stringify(redirect)}`
        )
      }
      return _createRoute(null, location)
    }

    const re: Object = redirect
    const { name, path } = re
    let { query, hash, params } = location
    query = re.hasOwnProperty('query') ? re.query : query
    hash = re.hasOwnProperty('hash') ? re.hash : hash
    params = re.hasOwnProperty('params') ? re.params : params

    if (name) {
      // resolved named direct
      const targetRecord = nameMap[name]
      if (process.env.NODE_ENV !== 'production') {
        assert(targetRecord, `redirect failed: named route "${name}" not found.`)

View on GitHub (pinned to 680ccc68c5)

Solutions

  1. Give redirect a valid value: a path string ('/b'), an object ({ path: '/b' } or { name: 'b' }), or a function returning one
  2. Remove the redirect option entirely if no redirect is intended
  3. If redirect comes from external config, validate its shape before building the route table
  4. Log JSON.stringify(redirect) (as the warning does) to see the actual offending value

Example fix

// before
{ path: '/old', redirect: null }
// after
{ path: '/old', redirect: '/new' }
Defensive patterns

Strategy: validation

Validate before calling

function isValidRedirect(redirect) {
  if (typeof redirect === 'string' && redirect.length > 0) return true
  if (redirect && typeof redirect === 'object' && (redirect.path || redirect.name)) return true
  return false
}
// before building routes: routes.forEach(r => { if ('redirect' in r && !isValidRedirect(r.redirect)) throw new Error('bad redirect on ' + r.path) })

Type guard

function isRedirectLocation(v) {
  return typeof v === 'string' || (v !== null && typeof v === 'object' && (typeof v.path === 'string' || typeof v.name === 'string'))
}

Prevention

When it happens

Trigger: Passing redirect: null, undefined, a number, a boolean, or an empty value in a route record; e.g. { path: '/a', redirect: null } or reading redirect from config that is missing. Note: a falsy redirect that survived the earlier truthiness checks reaches this branch.

Common situations: Routes generated dynamically from API/config data where the redirect field is absent or of the wrong type; typos like redirect: '/path' vs redirect: {name}; JSON configs where redirect was dropped during serialization.

Related errors


AI-assisted analysis of vuejs/vue-router@680ccc68c5 (2026-09-02). Data as JSON: /api/errors/1a09aa3aecf233a1. Report an issue: GitHub.