vercel/next.js · error · Error
Not a redirect error
Error message
Not a redirect error
What it means
`getRedirectTypeFromError` (redirect.ts:79) extracts the `push`/`replace` type from a `RedirectError`'s digest string. It guards with `isRedirectError(error)` and throws this literal `Error('Not a redirect error')` when the passed value is not a valid redirect error. The function is a narrow utility meant only for errors produced by `redirect()`/`permanentRedirect()`.
Source
Thrown at packages/next/src/client/components/redirect.ts:81
/**
* Returns the encoded URL from the error if it's a RedirectError, null
* otherwise. Note that this does not validate the URL returned.
*
* @param error the error that may be a redirect error
* @return the url if the error was a redirect error
*/
export function getURLFromRedirectError(error: RedirectError): string
export function getURLFromRedirectError(error: unknown): string | null {
if (!isRedirectError(error)) return null
// Slices off the beginning of the digest that contains the code and the
// separating ';'.
return error.digest.split(';').slice(2, -2).join(';')
}
export function getRedirectTypeFromError(error: RedirectError): RedirectType {
if (!isRedirectError(error)) {
throw new Error('Not a redirect error')
}
return error.digest.split(';', 2)[1] as RedirectType
}
export function getRedirectStatusCodeFromError(error: RedirectError): number {
if (!isRedirectError(error)) {
throw new Error('Not a redirect error')
}
return Number(error.digest.split(';').at(-2))
}
View on GitHub (pinned to 0ae8c72462)
Solutions
- Guard with `isRedirectError(error)` before calling `getRedirectTypeFromError(error)`.
- Re-throw or ignore non-redirect errors in your catch block instead of assuming all caught errors are redirects.
- Verify the error originates from `redirect()`/`permanentRedirect()`, not `notFound()`/`unauthorized()` which use a different digest.
Example fix
// before
try { await action() }
catch (e) {
const type = getRedirectTypeFromError(e) // throws if e isn't a redirect
}
// after
import { isRedirectError, getRedirectTypeFromError } from 'next/dist/client/components/redirect'
try { await action() }
catch (e) {
if (isRedirectError(e)) {
const type = getRedirectTypeFromError(e)
} else { throw e }
} Defensive patterns
Strategy: type-guard
Validate before calling
import { isRedirectError } from 'next/dist/client/components/redirect-error'
// Before calling getRedirectTypeFromError:
if (!isRedirectError(maybeErr)) {
throw new TypeError('Expected a RedirectError')
} Type guard
import { isRedirectError, type RedirectError } from 'next/dist/client/components/redirect-error'
function assertRedirectError(e: unknown): RedirectError {
if (!isRedirectError(e)) throw new Error('Not a redirect error')
return e
} Try / catch
try {
await action()
} catch (e) {
if (isRedirectError(e)) {
const type = getRedirectTypeFromError(e)
} else {
// not a redirect — handle or rethrow
throw e
}
} Prevention
- Always narrow with isRedirectError before calling getRedirectTypeFromError or getRedirectStatusCodeFromError.
- Never assume a caught error is a redirect; route handlers and actions can throw many error kinds.
- Centralize redirect-error handling in one helper that performs the guard once.
When it happens
Trigger: Passing an arbitrary caught error, a generic `Error`, `null`, or an error from a different Next.js subsystem (e.g. a notFound or unauthorized digest) into `getRedirectTypeFromError`. The `isRedirectError` check fails because the digest does not match the `NEXT_REDIRECT;type;url;status;` shape.
Common situations: A catch-all error handler that blindly pipes every caught error through redirect-extraction helpers without first narrowing; chaining `getURLFromRedirectError` and `getRedirectTypeFromError` assuming any error with a digest is a redirect; version mismatch where the digest format changed.
Related errors
- An unexpected response was received from the server.
- [inspect] ${route}: not an App Router document (no __next_f)
- Default export is missing in {resource_path}
- id property is required for every item returned from generat
- id property is required for every item returned from generat
AI-assisted analysis of vercel/next.js@0ae8c72462 (2026-08-06).
Data as JSON: /api/errors/3b49f4082a3fd9e1.
Report an issue: GitHub.