emberjs/ember.js · error · Error
infinite rendering invalidation detected
Error message
infinite rendering invalidation detected
What it means
During a Backburner loop-end flush, Ember re-validates renderers; if a renderer remains invalid after the rerender loop limit (ENV._RERENDER_LOOP_LIMIT), invalidation never converges, so Ember destroys the renderer and throws. This guards against endless revalidation (typically CP churn).
Source
Thrown at packages/@ember/-internals/glimmer/lib/base-renderer.ts:208
function resolveRenderPromise() {
if (renderSettledDeferred !== null) {
let resolve = renderSettledDeferred.resolve;
renderSettledDeferred = null;
_backburner.join(null, resolve);
}
}
let loops = 0;
function loopEnd() {
for (let renderer of renderers) {
if (!renderer.isValid()) {
if (loops > ENV._RERENDER_LOOP_LIMIT) {
loops = 0;
// TODO: do something better
renderer.destroy();
throw new Error('infinite rendering invalidation detected');
}
loops++;
return _backburner.join(null, NO_OP);
}
}
loops = 0;
resolveRenderPromise();
}
_backburner.on('begin', loopBegin);
_backburner.on('end', loopEnd);
type Resolver = ClassicResolver;
interface RendererData {
owner: object;
context: EvaluationContext;
builder: IBuilder;View on GitHub (pinned to 26f97246a8)
Solutions
- Find the self-invalidating computed/tracked property (log reads/writes) and make it stable (cache the array/object)
- Avoid mutating observed/tracked state inside getters or during render
- Break mutual dependencies between computeds
- Temporarily raise ENV._RERENDER_LOOP_LIMIT only to diagnose, not to fix
Example fix
// before
get items() {
return this.model.filter(x => x.active).map(x => ({ ...x })); // new array every access
}
// after
get items() {
return this.model.filter(x => x.active); // or memoize tracked state
} Defensive patterns
Strategy: validation
Validate before calling
// detect self-invalidating computeds in dev
get foo() { assert('no writes in getters', !this._writing); } Try / catch
try { renderApp(); } catch (e) { if (e.message === 'infinite rendering invalidation detected') { /* inspect recently-read tracked/computed props */ } throw e; } Prevention
- Never mutate tracked/observed state in getters or during render
- Return stable objects/arrays from computeds
- Avoid circular computed dependencies
- Run dev-mode observer/track validation regularly
When it happens
Trigger: Computed properties or observers whose getters invalidate themselves or each other; a template depending on a value that changes every time it's read; re-render loop exceeding the limit.
Common situations: A getter returning a new array/object each access feeding a tracked dependency; mutually dependent computeds; mutating state during render; ember-metal observer cycles after upgrades.
Related errors
- Attempted to rerender, but the Ember application has had an
- 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
AI-assisted analysis of emberjs/ember.js@26f97246a8 (2026-09-01).
Data as JSON: /api/errors/fec7c69134d5a400.
Report an issue: GitHub.