-
Notifications
You must be signed in to change notification settings - Fork 425
Description
The for:each and iterator directives require that the iterated child has a key attribute in order to guarantee proper rendering/reactivity. However, the code that validates the key attribute does not throw on invalid or duplicate keys. Instead, it simply logs an error in development mode, and does nothing in production mode.
lwc/packages/@lwc/engine-core/src/framework/api.ts
Lines 488 to 492 in e0029ee
| if (process.env.NODE_ENV !== 'production') { | |
| if (!isUndefined(iterationError)) { | |
| logError(iterationError, vmBeingRendered!); | |
| } | |
| } |
Although the framework warned against it, having duplicate keys mostly still worked as expected, for a long time. Recently, however, we introduced the lwc:on directive (#5344). A code path was introduced that assumes that a VM has an elm property that is always defined. However, when duplicate keys are used, this is not always the case, and an error is thrown due to an invalid weak map key.
| vm.attachedEventListeners.set(elm, attachedEventListeners); |
This does not always occur; we have not identified the root cause. Nevertheless, duplicate keys are invalid and now cause an actual error to occur, so we should make the error happen at the source, i.e. we should throw the duplicate key error rather than simply log it. This is a breaking change, so it must be done with API versioning.
With the new behavior enabled, the iterationError should always be thrown, regardless of NODE_ENV. On older API versions, the error should be a warning, rather than an error, because it is not thrown. It should also be logged regardless of NODE_ENV, and the message should be updated to include a notice that the behavior will change when components upgrade to the relevant API version.
Update: this isn't a safe change, so we've narrowed the scope. See #5540 (comment).