vuejs/vue-router · warning

Error decoding "${str}". Leaving it intact.

Error message

Error decoding "${str}". Leaving it intact.

What it means

decode wraps decodeURIComponent to decode query string keys and values. Some strings are invalid percent-encoding sequences (e.g. '%', '%zz', or truncated escapes like '%E0%A4' in the middle), and decodeURIComponent throws URIError on them. Instead of failing navigation, the library logs this warning and leaves the string undecoded so the query value is still usable.

Source

Thrown at src/util/query.js:22

const encodeReserveRE = /[!'()*]/g
const encodeReserveReplacer = c => '%' + c.charCodeAt(0).toString(16)
const commaRE = /%2C/g

// fixed encodeURIComponent which is more conformant to RFC3986:
// - escapes [!'()*]
// - preserve commas
const encode = str =>
  encodeURIComponent(str)
    .replace(encodeReserveRE, encodeReserveReplacer)
    .replace(commaRE, ',')

export function decode (str: string) {
  try {
    return decodeURIComponent(str)
  } catch (err) {
    if (process.env.NODE_ENV !== 'production') {
      warn(false, `Error decoding "${str}". Leaving it intact.`)
    }
  }
  return str
}

export function resolveQuery (
  query: ?string,
  extraQuery: Dictionary<string> = {},
  _parseQuery: ?Function
): Dictionary<string> {
  const parse = _parseQuery || parseQuery
  let parsedQuery
  try {
    parsedQuery = parse(query || '')
  } catch (e) {
    process.env.NODE_ENV !== 'production' && warn(false, e.message)
    parsedQuery = {}
  }

View on GitHub (pinned to 680ccc68c5)

Solutions

  1. Fix the source of the URL to properly percent-encode: encodeURIComponent('100%') produces '100%25'.
  2. Sanitize/repair the incoming query string before navigation (replace stray '%' with '%25').
  3. On the server, normalize malformed query params before redirecting into the SPA.
  4. If the value is user-supplied and cannot be trusted, decode manually with try/catch and use the raw value (the library already does this — the warning is informational).

Example fix

// before
const url = `/search?q=${term}` // term = '100%'
// after
const url = `/search?q=${encodeURIComponent(term)}` // 'q=100%25'
Defensive patterns

Strategy: fallback

Validate before calling

function isDecodable (str) {
  try { decodeURIComponent(str); return true } catch (e) { return false }
}
// check query values from external input before navigation

Try / catch

let q
try { q = decodeURIComponent(raw) } catch (e) { q = raw // leave intact, as vue-router does
  console.warn('undecodable query value:', raw) }

Prevention

When it happens

Trigger: Navigating to a URL whose query string contains a malformed percent-escape: e.g. /search?q=100% or /page?name=%E0%A4%A when parseQuery invokes decode on key or val. The raw query string is preserved (intact) rather than decoded.

Common situations: Users pasting URLs with unencoded '%' characters (very common: '50% off', '100%'); external systems generating invalid escapes; server redirects carrying already-decoded percent signs; truncated escapes from string slicing/copy-paste.

Related errors


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