Skip to content

"TypeError: view[EFFECTS] is not iterable" when effect causes a component to no longer exist #62822

Description

@glenstaes

Which @angular/* package(s) are the source of the bug?

core

Is this a regression?

No

Description

We have set up an effect that closes a dialog when an httpResource returns a certain response. When closing the dialog, we clean up the effect by calling .destroy() on the effectRef, however we still get an error that view[EFFECTS] is not iterable.

This error originates from runEffectsInView:

function runEffectsInView(view) {
    if (view[EFFECTS] === null) {
        return;
    }
    // Since effects can make other effects dirty, we flush them in a loop until there are no more to
    // flush.
    let tryFlushEffects = true;
    while (tryFlushEffects) {
        let foundDirtyEffect = false;
        for (const effect of view[EFFECTS]) { // <-- ERROR IS THROWN HERE
            if (!effect.dirty) {
                continue;
            }
            foundDirtyEffect = true;
            // `runEffectsInView` is called during change detection, and therefore runs
            // in the Angular zone if it's available.
            if (effect.zone === null || Zone.current === effect.zone) {
                effect.run();
            }
            else {
                effect.zone.run(() => effect.run());
            }
        }
        // Check if we need to continue flushing. If we didn't find any dirty effects, then there's
        // no need to loop back. Otherwise, check the view to see if it was marked for traversal
        // again. If so, there's a chance that one of the effects we ran caused another effect to
        // become dirty.
        tryFlushEffects = foundDirtyEffect && !!(view[FLAGS] & 8192 /* LViewFlags.HasChildViewsToRefresh */);
    }
}

Within the for-loop, the effect that closes the dialog is run, causing view[EFFECTS] to become null. The tryFlushEffects assignment doesn't take this into account, meaning that it is true and runs the while-loop again. Because the while-loop is entered again, the for-loop is invoked again, but view[EFFECTS] now gives us null, raising the error.

Please provide a link to a minimal reproduction of the bug

No response

Please provide the exception or error you saw

root_effect_scheduler.mjs:3583 ERROR TypeError: view[EFFECTS] is not iterable
    at runEffectsInView (debug_node.mjs:8819:30)
    at detectChangesInView (debug_node.mjs:9186:17)
    at detectChangesInViewIfAttached (debug_node.mjs:9139:5)
    at detectChangesInEmbeddedViews (debug_node.mjs:9096:13)
    at refreshView (debug_node.mjs:8988:9)
    at detectChangesInView (debug_node.mjs:9179:9)
    at detectChangesInViewIfAttached (debug_node.mjs:9139:5)
    at detectChangesInComponent (debug_node.mjs:9127:5)
    at detectChangesInChildComponents (debug_node.mjs:9205:9)
    at refreshView (debug_node.mjs:9014:13)

Please provide the environment you discovered this bug in (run ng version)

Angular CLI: 20.1.1
Node: 22.13.0
Package Manager: npm 10.9.2
OS: win32 x64

Angular: 20.1.1
... animations, build, cli, common, compiler, compiler-cli, core
... forms, localize, platform-browser, platform-browser-dynamic
... router, service-worker

Package                      Version
------------------------------------------------------
@angular-devkit/architect    0.2001.0
@angular-devkit/core         20.1.1
@angular-devkit/schematics   20.1.1
@angular/cdk                 20.1.2
@schematics/angular          20.1.1
ng-packagr                   20.1.0
rxjs                         7.8.1
typescript                   5.8.3
zone.js                      0.15.0

Anything else?

Changing the tryFlushEffects assignment to the following (including an extra check for view[EFFECTS]) resolves the issue.

tryFlushEffects = foundDirtyEffect && !!(view[FLAGS] & 8192 /* LViewFlags.HasChildViewsToRefresh */) && view[EFFECTS] !== null;

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: coreIssues related to the framework runtimecore: reactivityWork related to fine-grained reactivity in the core frameworkworkaround1: obvious

    Type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions