vuejs/vue-router · warning
Error decoding " ". 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.
Solutions
- Fix the source of the URL to properly percent-encode: encodeURIComponent('100%') produces '100%25'.
- Sanitize/repair the incoming query string before navigation (replace stray '%' with '%25').
- On the server, normalize malformed query params before redirecting into the SPA.
- 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
- Always encodeURIComponent user-generated values before building URLs.
- Never double-decode strings that may already be decoded.
- Sanitize inbound URLs server-side (fix stray '%' before redirecting into the SPA).
- Watch for this warning in dev; it means query data is being passed through raw.
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
- ${e.message}
- Duplicate named routes definition
- Duplicate param keys in route with path
- Failed to resolve async component
- Found an alias with the same value as the path
AI-assisted analysis of vuejs/vue-router@680ccc68c5 (2026-09-02).
Data as JSON: /api/errors/b68934944d47da48.
Report an issue: GitHub.
Appendix: 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)