emberjs/ember.js · critical

Attempted to rerender, but the Ember application has had an

Error message

Attempted to rerender, but the Ember application has had an unrecoverable error occur during render. You should reload the application after fixing the cause of the error.

What it means

In base-renderer, after a render pass throws, errorLoopTransaction replaces the render function with a noop that console.warns this message, preventing infinite rerender loops when Ember retries rendering after an unrecoverable error. Hitting this means a previous render errored so badly the renderer disabled further renders until reload.

Source

Thrown at packages/@ember/-internals/glimmer/lib/base-renderer.ts:56

// This wrapper logic prevents us from rerendering in case of a hard failure
// during render. This prevents infinite revalidation type loops from occuring,
// and ensures that errors are not swallowed by subsequent follow on failures.
export function errorLoopTransaction(fn: () => void) {
  if (DEBUG) {
    return () => {
      let didError = true;

      try {
        fn();
        didError = false;
      } finally {
        if (didError) {
          // Noop the function so that we won't keep calling it and causing
          // infinite looping failures;
          fn = () => {
            // eslint-disable-next-line no-console
            console.warn(
              'Attempted to rerender, but the Ember application has had an unrecoverable error occur during render. You should reload the application after fixing the cause of the error.'
            );
          };
        }
      }
    };
  } else {
    return fn;
  }
}

/**
 * The interface the `RendererState` needs from a render root. The base
 * renderer only ever creates `ComponentRootState`s; the classic renderer
 * (`./renderer`) adds `ClassicRootState` for outlet/classic-component roots.
 */
export interface RendererRoot {
  readonly type: string;

View on GitHub (pinned to 26f97246a8)

Solutions

  1. Fix the root cause: find the original error logged before this warning (scroll up in console) and repair the component/template/helper.
  2. Reload the application after deploying the fix, as the renderer cannot recover in-session.
  3. Guard templates against undefined/null values that crash helpers.
  4. Wrap risky computed/helper logic in try/catch or safe defaults.

Example fix

// before
{{(this.items.firstObject.name.toUpperCase)}}
// after
{{(if this.items.firstObject (uppercase this.items.firstObject.name) '')}}
Defensive patterns

Strategy: validation

Validate before calling

// Validate render inputs before they hit templates
function assertRenderSafe(component) {
  if (component.args == null) throw new Error('component rendered without args');
}
assertRenderSafe(this);

Type guard

function isRenderable(v) { return v !== undefined && v !== null; }

Try / catch

// The renderer turns the rerender fn into a console.warn noop; treat the warning as fatal
window.addEventListener('error', e => {
  if (String(e.message).includes('Attempted to rerender')) { reportFatalRenderLoop(); }
});

Prevention

When it happens

Trigger: A template/component render threw an exception; the renderer's error loop attempted to rerender and the poisoned fn warned instead of rendering again.

Common situations: Bugs in a component template/helper crashing during render (undefined property access in strict helpers, infinite recursion); Glimmer VM internal errors; development-time HMR bugs; corrupted component state after a thrown error.

Related errors


AI-assisted analysis of emberjs/ember.js@26f97246a8 (2026-09-01). Data as JSON: /api/errors/ab10f653d10c65b2. Report an issue: GitHub.