In a 3D scene that supports replacing models at runtime, changing the visible asset does not always mean that every interaction attached to that asset has been rebuilt as well.
I ran into this in a combined prototype. After switching to a new model file, distance measurement, notes, and the cube tool stopped responding to clicks on the model. Volume measurement, however, still worked.
At first, that pattern looked like several feature-specific failures. Further debugging showed that the issue was lower in the stack: the new model was visible, but its pointer events had not been registered correctly.
The important distinction was this: the visual content had changed, but the framework still considered the surrounding component to be the same identity. When downstream behavior is registered against object references, reusing that identity can leave event or subscription state attached to the old object graph.
The root-cause diagnosis and implementation fix mainly came from Claude Code. My role was to verify the behavior across multiple replacement models and retest every affected interaction.
The model-loading component did not have an identity that changed with the model source.
When the URL changed, the framework reused the existing outer component instance and replaced its internal model content instead of fully unmounting the old instance and mounting a new one.
For visual rendering, that was enough. The new model appeared correctly.
The event system, however, depended on object references and node registration. Because the surrounding identity stayed the same, the downstream hit-testing and pointer-event setup did not reliably rebuild around the new model graph.
The result was a scene that looked correct while even the lowest-level pointer down and pointer up events were missing.
This is what makes the bug difficult to recognize: the resource itself appears to have loaded successfully. What has become stale is the set of relationships built around that resource.
The fix was to give the model-loading component an explicit identity tied to the model source.
When the model URL changes, that identity changes as well. The framework then treats the new model as a new component instance rather than an update to the old one, forcing a full unmount and remount.
That rebuilds the container, model-node references, and the event registrations that depend on them.
The broader rule is not that everything should always be remounted. It is that when a resource change represents a real object-identity change, the framework needs to be told that the identity changed as well.
Reuse is useful when the underlying object is still conceptually the same. It becomes risky when downstream systems use the object reference itself as the basis for capabilities such as events or subscriptions.
Tie the model-loading component's identity to the model source, for example with a key based on the model URL.
A source change then triggers a full remount so refs, event registration, and related side effects are rebuilt.
During debugging, confirm the lowest-level pointer events first before moving upward into hit testing or feature-specific logic.
The most misleading clue was that volume measurement remained functional.
Distance measurement, notes, and the cube tool all require the user to hit the model surface, so they depend on pointer events reaching the model nodes.
Volume measurement follows a different path. It mainly uses the scene's overall bounding box to establish a reference plane and does not require the same surface hit interaction.
So volume measurement did not avoid the same bug. It simply did not use the broken dependency chain.
That is an important debugging distinction: one feature still working does not prove that the shared lower-level system is mostly healthy. It may only mean that the feature does not depend on that system at all.
Starting from the individual feature logic would have made this issue much harder to isolate.
A more useful order is to move upward from the lowest shared layer:
If the first step never happens, there is little value in inspecting measurement algorithms, note logic, or cube creation behavior.
When several features fail together, the shared layer should usually be investigated before each feature is treated as an independent problem.
This issue appeared only after model replacement was introduced.
When adding dynamic resource loading, it is easy to test only whether:
But every interaction that depends on that resource should also be retested: selection, measurement, annotation, object creation, and other hit-based behavior.
A resource replacement can affect more than content. It can also affect identity, lifecycle, event registration, cached references, and subscriptions.
So the validation question should not stop at "did the new asset appear?" It should also ask whether the capabilities that were attached to the old asset were correctly rebuilt around the new one.
The specific cause of the stale event binding and the remount fix were mainly identified with Claude Code. My responsibility was to verify that the failure really came from a shared lower-level mechanism and to confirm that every dependent interaction recovered after the model change.
The reusable lesson is broader than "remember to add a key." It is this: whenever capabilities are established around an object reference, framework-level identity reuse can become dangerous if the content has changed but those downstream relationships have not been rebuilt.
The same pattern can apply to events, subscriptions, observers, caches, and other side effects that depend on object identity.