emberjs/ember.js · error · TransitionError
TransitionError
Error message
TransitionError
What it means
TransitionState.handleError wraps an error thrown during a transition (in a route hook like beforeModel/model/afterModel) in a TransitionError carrying the failing RouteInfo, whether the transition was aborted, and the state. The message is always 'TransitionError'; the original cause is on the `.cause`/error property. It signals the transition failed mid-flight at the given resolve index.
Source
Thrown at packages/router_js/lib/transition-state.ts:26
interface IParams {
[key: string]: unknown;
}
function handleError<R extends Route>(
currentState: TransitionState<R>,
transition: Transition<R>,
error: Error
): never {
// This is the only possible
// reject value of TransitionState#resolve
let routeInfos = currentState.routeInfos;
let errorHandlerIndex =
transition.resolveIndex >= routeInfos.length ? routeInfos.length - 1 : transition.resolveIndex;
let wasAborted = transition.isAborted;
throw new TransitionError(
error,
currentState.routeInfos[errorHandlerIndex]!.route!,
wasAborted,
currentState
);
}
function resolveOneRouteInfo<R extends Route>(
currentState: TransitionState<R>,
transition: Transition<R>
): void | Promise<void> {
if (transition.resolveIndex === currentState.routeInfos.length) {
// This is is the only possible
// fulfill value of TransitionState#resolve
return;
}
let routeInfo = currentState.routeInfos[transition.resolveIndex]!;View on GitHub (pinned to 26f97246a8)
Solutions
- Inspect error.cause / the wrapped error to find the real failure.
- Add error handling in route hooks (try/catch or .catch) or an application-level error route/action.
- Handle the rejection where transitionTo is called: router.transitionTo(...).catch(fn).
- Use error routes (this.route('error', { path: '*:' })) or route error actions to recover gracefully.
Example fix
// before
router.transitionTo('post', id); // unhandled rejection wraps the API failure
// after
router.transitionTo('post', id).catch((e) => {
console.error('transition failed:', e.cause ?? e);
}); Defensive patterns
Strategy: try-catch
Validate before calling
// Validate route-hook preconditions before transitioning
async function safeTransition(router, name, model) {
if (!model) return router.transitionTo('index');
return router.transitionTo(name, model);
} Type guard
function isTransitionError(e) { return e instanceof Error && e.message === 'TransitionError'; } Try / catch
router.transitionTo('post', id).catch(e => {
if (isTransitionError(e)) {
const cause = e.cause ?? e.error;
console.error('transition hook failed:', cause);
router.transitionTo('error');
}
}); Prevention
- Add error actions on routes (route's `actions.error`) for graceful recovery.
- Wrap model-hook fetches with .catch and redirect on failure.
- Always attach .catch to transitionTo/handleURL calls.
- Define an application-level error route.
When it happens
Trigger: Any route hook throws or rejects during transitionTo/handleURL; router handles it via handleError and rethrows as TransitionError.
Common situations: Model hooks rejecting on API failure; beforeModel redirects gone wrong; unhandled promise rejections in route lifecycle; assertion errors from guards.
Related errors
- Programmatic transitions by URL cannot be used within an Eng
- You attempted to mount the engine '${name}', but it is not r
- Defining a route serializer on route '${name}' outside an En
- Defining a custom serialize method on an Engine route is not
- More context objects were passed than there are dynamic segm
AI-assisted analysis of emberjs/ember.js@26f97246a8 (2026-09-01).
Data as JSON: /api/errors/cd73cc5588d79acf.
Report an issue: GitHub.