vercel/next.js · error · DecodeError
Failed to decode path param(s).
Error message
Failed to decode path param(s).
What it means
Thrown by decodePathParams (as a DecodeError) when a path segment contains malformed percent-encoding that decodeURIComponent cannot parse (e.g. '%zz' or a lone '%' at the end). Next.js decodes URL path params to match dynamic routes, and invalid escapes make decoding impossible.
Source
Thrown at packages/next/src/server/lib/router-utils/decode-path-params.ts:21
/**
* We only encode path delimiters for path segments from
* getStaticPaths so we need to attempt decoding the URL
* to match against and only escape the path delimiters
* this allows non-ascii values to be handled e.g.
* Japanese characters.
* */
function decodePathParams(pathname: string): string {
// TODO: investigate adding this handling for non-SSG
// pages so non-ascii names also work there.
return pathname
.split('/')
.map((seg) => {
try {
seg = escapePathDelimiters(decodeURIComponent(seg), true)
} catch (_) {
// An improperly encoded URL was provided
throw new DecodeError('Failed to decode path param(s).')
}
return seg
})
.join('/')
}
export { decodePathParams }
View on GitHub (pinned to 0ae8c72462)
Solutions
- Ensure the client sends properly percent-encoded URLs (e.g. %20 for space, %25 for a literal %).
- If a proxy is double-encoding, fix the proxy to pass the raw path through.
- Add a rewrite or middleware to sanitize/normalize incoming paths before they reach the router.
- For genuinely malformed requests, expect a 400 and ensure your error page handles it gracefully.
Example fix
// before: client sends a raw percent // GET /files/report%.pdf -> throws DecodeError // after: client encodes the percent // GET /files/report%25.pdf
Defensive patterns
Strategy: try-catch
Validate before calling
function isDecodablePath(pathname: string): boolean {
return pathname.split('/').every(seg => {
try { decodeURIComponent(seg); return true } catch { return false }
})
} Type guard
function isDecodablePath(pathname: string): boolean {
try { decodeURIComponent(pathname); return true } catch { return false }
} Try / catch
try {
decodePathParams(pathname)
} catch (e) {
if (e instanceof DecodeError) return new Response('Bad Request', { status: 400 })
throw e
} Prevention
- Always percent-encode special characters in generated URLs.
- Normalize/validate paths in middleware before they reach the router.
- Watch for proxies that double-encode paths.
When it happens
Trigger: A request URL contains a path segment with an invalid percent-escape sequence, such as /post/%zz or /user/100%. decodeURIComponent throws URIError which is rethrown as DecodeError.
Common situations: Clients sending unencoded special characters, a reverse proxy double-decoding/encoding, or a misconfigured redirect that mangles the path. Bots/scanners hitting odd URLs also trigger this.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to decode param
- Each route must start with '/': ${route}
- The provided export path '${pathname}' doesn't match the '${
- > Couldn't find any `pages` or `app` directory. Please creat
- > `pages` and `app` directories should be under the same fol
AI-assisted analysis of vercel/next.js@0ae8c72462 (2026-08-06).
Data as JSON: /api/errors/bc316d32fe9d3570.
Report an issue: GitHub.