From b5215013bde00482db16b1c76350e1be1d99dc3c Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Tue, 3 Mar 2026 15:27:13 -0500 Subject: [PATCH 1/2] Fix #20984: crash *during* destroy in fastboot --- packages/@ember/-internals/glimmer/lib/renderer.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/@ember/-internals/glimmer/lib/renderer.ts b/packages/@ember/-internals/glimmer/lib/renderer.ts index 2a0847d4818..96824559dea 100644 --- a/packages/@ember/-internals/glimmer/lib/renderer.ts +++ b/packages/@ember/-internals/glimmer/lib/renderer.ts @@ -232,7 +232,16 @@ class ClassicRootState { let result = (this.result = iterator.sync()); - associateDestroyableChild(owner, result); + // Associate the result with the root state (not the owner) so that + // destruction cascades through: + // Owner → Container → Renderer → RendererState → ClassicRootState → result + // This ensures the container is still alive when component destructors + // run (e.g. willDestroy looking up the renderer via injection). + // Previously, associating with the owner made the result a sibling of + // the Container, causing the Container to be destroyed first — which + // broke FastBoot where the container was already dead by the time + // component teardown tried to do lookups. (See: emberjs/ember.js#20984) + associateDestroyableChild(this, result); this.render = errorLoopTransaction(() => { if (isDestroying(result) || isDestroyed(result)) return; From 00e7e184bf3e67ba800ef3598fc4630a48cb0aaf Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Tue, 3 Mar 2026 15:52:50 -0500 Subject: [PATCH 2/2] Clean up comments in renderer.ts Remove outdated comments regarding result association with root state. --- packages/@ember/-internals/glimmer/lib/renderer.ts | 9 --------- 1 file changed, 9 deletions(-) diff --git a/packages/@ember/-internals/glimmer/lib/renderer.ts b/packages/@ember/-internals/glimmer/lib/renderer.ts index 96824559dea..0bcd9cd7b19 100644 --- a/packages/@ember/-internals/glimmer/lib/renderer.ts +++ b/packages/@ember/-internals/glimmer/lib/renderer.ts @@ -232,15 +232,6 @@ class ClassicRootState { let result = (this.result = iterator.sync()); - // Associate the result with the root state (not the owner) so that - // destruction cascades through: - // Owner → Container → Renderer → RendererState → ClassicRootState → result - // This ensures the container is still alive when component destructors - // run (e.g. willDestroy looking up the renderer via injection). - // Previously, associating with the owner made the result a sibling of - // the Container, causing the Container to be destroyed first — which - // broke FastBoot where the container was already dead by the time - // component teardown tried to do lookups. (See: emberjs/ember.js#20984) associateDestroyableChild(this, result); this.render = errorLoopTransaction(() => {