emberjs/ember.js · error · Error
You can't call rerender on a view being destroyed
Error message
You can't call rerender on a view being destroyed
What it means
Ember view lifecycle states enforce which operations are legal on a view. When a view has entered the 'destroying' state, calling rerender() is forbidden because the view's renderer and DOM context are being torn down. The states machine in states.ts throws this Error to prevent re-render work on a dead view.
Source
Thrown at packages/@ember/-internals/views/lib/views/states.ts:105
set(value) {
if (value !== elementId) {
throw new Error("Changing a view's elementId after creation is not allowed");
}
},
});
}
},
});
const DESTROYING: Readonly<ViewState> = Object.freeze({
...DEFAULT,
appendChild() {
throw new Error("You can't call appendChild on a view being destroyed");
},
rerender() {
throw new Error("You can't call rerender on a view being destroyed");
},
});
/*
Describe how the specified actions should behave in the various
states that a view can exist in. Possible states:
* preRender: when a view is first instantiated, and after its
element was destroyed, it is in the preRender state
* hasElement: the DOM representation of the view is created,
and is ready to be inserted
* inDOM: once a view has been inserted into the DOM it is in
the inDOM state. A view spends the vast majority of its
existence in this state.
* destroyed: once a view has been destroyed (using the destroy
method), it is in this state. No further actions can be invoked
on a destroyed view.
*/View on GitHub (pinned to 26f97246a8)
Solutions
- Guard rerender calls with an isDestroying/isDestroyed check
- Cancel async work in willDestroy (cancel timers, resolve/abort promises)
- Use @ember/runloop schedule/cancel so pending work is cancelled on teardown
- Remove event listeners and observers on destroy
Example fix
// before
didReceiveAttrs() {
fetch('/data').then(() => this.rerender());
}
// after
didReceiveAttrs() {
fetch('/data').then(() => {
if (!this.isDestroying && !this.isDestroyed) this.rerender();
});
} Defensive patterns
Strategy: validation
Validate before calling
if (!view.isDestroying && !view.isDestroyed) { view.rerender(); } Type guard
function canRerender(view) { return view && !view.isDestroying && !view.isDestroyed; } Try / catch
try { view.rerender(); } catch (e) { if (!/being destroyed/.test(e.message)) throw e; /* ignore teardown race */ } Prevention
- Check isDestroying/isDestroyed before any late async DOM work
- Cancel runloop timers and async tasks in willDestroy
- Use lifecycle-safe patterns ({{modify}} / decorators) that no-op after teardown
- Avoid raw setTimeout for UI updates
When it happens
Trigger: Calling view.rerender() after the view has begun destruction — e.g. during willDestroyElement, willDestroy, or from a component triggered asynchronously (timer, promise) that resolves after the component is being destroyed.
Common situations: Async callbacks (setTimeout, debounce, promise resolution, event listeners) firing while a component unmounts during route transition; tests that tear down the app while rerender is queued.
Related errors
- Cannot call `.lookup('${fullName}')` after the owner has bee
- Cannot call `.factoryFor('${fullName}')` after the owner has
- You attempted to set "${String(prop)}" on a factory manager
- Could not create factory
- Cannot create new instances after the owner has been destroy
AI-assisted analysis of emberjs/ember.js@26f97246a8 (2026-09-01).
Data as JSON: /api/errors/7ed5ccb1703bead4.
Report an issue: GitHub.