{"record":{"id":"3b49f4082a3fd9e1","repo":"vercel/next.js","slug":"not-a-redirect-error","errorCode":null,"errorMessage":"Not a redirect error","messagePattern":"Not a redirect error","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/next/src/client/components/redirect.ts","lineNumber":81,"sourceCode":"/**\n * Returns the encoded URL from the error if it's a RedirectError, null\n * otherwise. Note that this does not validate the URL returned.\n *\n * @param error the error that may be a redirect error\n * @return the url if the error was a redirect error\n */\nexport function getURLFromRedirectError(error: RedirectError): string\nexport function getURLFromRedirectError(error: unknown): string | null {\n  if (!isRedirectError(error)) return null\n\n  // Slices off the beginning of the digest that contains the code and the\n  // separating ';'.\n  return error.digest.split(';').slice(2, -2).join(';')\n}\n\nexport function getRedirectTypeFromError(error: RedirectError): RedirectType {\n  if (!isRedirectError(error)) {\n    throw new Error('Not a redirect error')\n  }\n\n  return error.digest.split(';', 2)[1] as RedirectType\n}\n\nexport function getRedirectStatusCodeFromError(error: RedirectError): number {\n  if (!isRedirectError(error)) {\n    throw new Error('Not a redirect error')\n  }\n\n  return Number(error.digest.split(';').at(-2))\n}\n","sourceCodeStart":63,"sourceCodeEnd":94,"githubUrl":"https://github.com/vercel/next.js/blob/0ae8c72462952df163f1b1e0726641bc5b40dc93/packages/next/src/client/components/redirect.ts#L63-L94","documentation":"`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()`.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\ntry { await action() }\ncatch (e) {\n  const type = getRedirectTypeFromError(e) // throws if e isn't a redirect\n}\n\n// after\nimport { isRedirectError, getRedirectTypeFromError } from 'next/dist/client/components/redirect'\ntry { await action() }\ncatch (e) {\n  if (isRedirectError(e)) {\n    const type = getRedirectTypeFromError(e)\n  } else { throw e }\n}","handlingStrategy":"type-guard","validationCode":"import { isRedirectError } from 'next/dist/client/components/redirect-error'\n// Before calling getRedirectTypeFromError:\nif (!isRedirectError(maybeErr)) {\n  throw new TypeError('Expected a RedirectError')\n}","typeGuard":"import { isRedirectError, type RedirectError } from 'next/dist/client/components/redirect-error'\nfunction assertRedirectError(e: unknown): RedirectError {\n  if (!isRedirectError(e)) throw new Error('Not a redirect error')\n  return e\n}","tryCatchPattern":"try {\n  await action()\n} catch (e) {\n  if (isRedirectError(e)) {\n    const type = getRedirectTypeFromError(e)\n  } else {\n    // not a redirect — handle or rethrow\n    throw e\n  }\n}","preventionTips":["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."],"tags":["redirect","error-handling","app-router","type-guard"],"analyzedSha":"0ae8c72462952df163f1b1e0726641bc5b40dc93","analyzedAt":"2026-08-06T19:44:29.143Z","schemaVersion":2},"datasetVersion":"2026-08-07T02:17:10.218Z"}