# AUR0764-0765

## Error Message

`AUR0764: Trying to retrieve a custom element controller from a node. But the provided node <{{nodeName}} /> does not appear to be part of an Aurelia app DOM tree, or it was added to the DOM in a way that Aurelia cannot properly resolve its position in the component tree.`

`AUR0765: Trying to retrieve a custom element controller from a node. But the provided node <{{nodeName}} /> does not appear to be part of an Aurelia app DOM tree, or it was added to the DOM in a way that Aurelia cannot properly resolve its position in the component tree.`

Where `{{nodeName}}` is the tag name of the DOM node provided.

## Description

These errors occur when Aurelia tries to locate the nearest component controller associated with a given DOM node by traversing up the DOM tree (using the internal `CustomElement.findController` method, which might be called by other APIs). The traversal failed to find any recognized Aurelia component boundary before reaching the top of the document or a shadow root boundary. This indicates the provided node is likely outside the part of the DOM managed by the Aurelia application instance.

## Cause

1. **External Node:** The target node exists in the DOM but was created and appended outside the control of the Aurelia application (e.g., via direct `document.createElement`, `innerHTML` manipulation, or by a non-Aurelia library). Aurelia doesn't automatically associate controllers with such nodes.
2. **Detached Node:** The node might have been part of an Aurelia component initially but was removed from the Aurelia-managed DOM tree before the controller lookup was attempted.
3. **Incorrect Application Root:** The Aurelia application might not have been started correctly on a container element that encompasses the target node.
4. **Shadow DOM Issues:** If using Shadow DOM extensively, the traversal might stop at a shadow root boundary if the lookup wasn't initiated from within that shadow root's context correctly.
5. **Timing/Lifecycle:** Attempting the lookup before the node and its parent components have been fully processed and attached by Aurelia.

## Solution

1. **Ensure Node is Aurelia-Managed:** Verify that the target node was rendered as part of an Aurelia component's template or dynamically composed using Aurelia APIs (like `au-compose` or view slot manipulation). Avoid manipulating the DOM managed by Aurelia using external methods if you need to interact with controllers later.
2. **Correct Starting Point:** Ensure the code attempting to find the controller is executing within the context of the Aurelia application and that the target node is a descendant of the application's root element.
3. **Use `CustomElement.for(node)` first:** If you intend to get the controller *for* a specific custom element host node, use `CustomElement.for(node)` (see AUR0762/AUR0763) first. `findController` is more for finding the nearest *owning* controller *from* an arbitrary node within a component's view.
4. **Check Lifecycle:** Ensure the lookup occurs after the relevant parts of the DOM have been attached and rendered by Aurelia (e.g., in `attached` lifecycle hooks, after awaiting relevant promises).

## Example

```html
<!-- Assume this is outside the Aurelia root element -->
<div id="external-div">External Content</div>

<!-- Assume this is the Aurelia root -->
<div id="aurelia-root">
  <my-app></my-app>
</div>
```

```typescript
import { CustomElement, IPlatform } from 'aurelia';

// Assume MyApp component exists and is the root of the Aurelia app within #aurelia-root

export class SomeService {
  constructor(private platform: IPlatform) {}

  findControllerForExternalNode() {
    // This node is likely outside Aurelia's managed tree
    const externalNode = this.platform.document.getElementById('external-div');

    if (externalNode) {
      this.platform.domReadQueue.queueTask(() => {
        try {
          // This will likely fail as the walk up from externalNode won't hit an Aurelia controller
          const controller = CustomElement.findController(externalNode); // Throws AUR0764/AUR0765
          console.log('Found controller:', controller);
        } catch (e) {
          console.error('Error finding controller for external node:', e);
        }
      });
    }
  }

  // Correct usage: Finding controller from within a managed component
  findControllerFromInside(someNodeInsideAureliaComponent: Node) {
     this.platform.domReadQueue.queueTask(() => {
        try {
          // This should succeed if someNodeInsideAureliaComponent is part of a rendered component
          const controller = CustomElement.findController(someNodeInsideAureliaComponent);
          console.log('Found owning controller:', controller);
        } catch (e) {
          console.error('Error finding controller:', e);
        }
      });
  }
}
```

## Debugging Tips

* Inspect the target node and its ancestors in the browser's element inspector. Verify it is indeed inside the DOM element where your Aurelia app was started (`Aurelia.app({ host: ..., component: ... })`).
* Check how the target node was added to the DOM. Was it via an Aurelia template, or some other mechanism?
* If added dynamically, ensure it was done using Aurelia-aware mechanisms if controller association is needed.
* Set breakpoints in `CustomElement.findController` (if possible in development builds) or log the node being passed to it to confirm it's the expected one.
