# AUR0503

## Error Message

`AUR0503: Controller at <ControllerName> is in an unexpected state: <State> during activation.`

Where:

* `<ControllerName>` is the name of the controller.
* `<State>` is the unexpected state the controller was found in (e.g., `activating`, `deactivating`, `disposed`).

## Description

This error occurs during the activation phase of a component's lifecycle when Aurelia finds that the controller is not in one of the expected states (`created`, `bound`, or `attached`). Activation should only proceed from these states; finding the controller in another state (like `activating`, `deactivating`, or `disposed`) indicates a potential lifecycle mismatch or corruption.

## Cause

This error usually points to deeper issues with lifecycle management, often related to:

1. **Re-entrant Activation:** An attempt to activate a controller that is already in the process of activating or deactivating. This could happen with complex asynchronous operations or event handling within lifecycle methods.
2. **Lifecycle Interference:** Custom code directly manipulating the controller's state or calling lifecycle methods out of sequence.
3. **Concurrency Issues:** Multiple asynchronous operations trying to manipulate the same controller's lifecycle concurrently without proper coordination.
4. **Framework Bug (Less Common):** In rare cases, an internal issue within the Aurelia framework could lead to inconsistent state management.

## Solution

1. **Analyze Activation Triggers:** Determine what triggers the activation process for this component. Is it standard routing/composition, or is there custom code involved (e.g., manually calling `controller.activate`)?
2. **Simplify Lifecycle Logic:** Review the component's lifecycle hooks (`activate`, `binding`, `bound`, `attaching`, `detaching`, `unbinding`). Avoid complex, nested, or re-entrant calls within these hooks, especially those involving asynchronous operations that might trigger further lifecycle changes.
3. **Synchronize Concurrent Operations:** If multiple asynchronous tasks can affect the component's lifecycle, ensure they are properly synchronized or that they check the controller's state before proceeding.
4. **Avoid Manual State Changes:** Do not manually set the `controller.state` property. Rely on Aurelia's standard lifecycle flow.
5. **Isolate the Problem:** Try simplifying the component or the scenario where the error occurs to isolate the cause. Does it happen with a minimal component? Does it only happen under specific navigation patterns or data conditions?

## Example

```typescript
import { customElement, ICustomElementController } from 'aurelia';

@customElement({ name: 'complex-lifecycle', template: '...' })
export class ComplexLifecycle {
  public controller!: ICustomElementController<this>;

  // --- Potentially Problematic Patterns ---

  async activate(params: unknown) {
    // If this method somehow triggers another activation of the *same*
    // controller instance before the first one completes, it could lead to AUR0503.
    console.log('Activating...');
    await this.loadInitialData();

    // Example: Incorrectly trying to re-activate based on some condition
    // if (someCondition) {
    //   console.log('Trying to re-activate...');
    //   // Manually calling activate again on the same controller is usually wrong
    //   // and could lead to unexpected states if not handled perfectly (which is hard).
    //   await this.controller.activate(this.controller, this.controller.parentController); // DANGEROUS
    // }
  }

  async loadInitialData() {
    // Simulate async work
    await new Promise(resolve => setTimeout(resolve, 100));
  }

  // Consider also binding/bound/attaching hooks if they perform
  // async operations that might interfere with ongoing activation/deactivation.

  // --- Safer approach ---
  // Ensure lifecycle methods are idempotent or handle state checks carefully.
  // Let Aurelia manage the primary activation flow. If re-initialization
  // is needed based on new data, use standard data-binding updates
  // or parameter changes handled by the router/composition, which trigger
  // appropriate lifecycle events, rather than manual re-activation calls.

}

// --- External Code Example (Problematic) ---
// function triggerExternalActivation(controller: ICustomElementController) {
//   // If this function is called while the controller is already activating
//   // or in another non-idle state, it could lead to AUR0503.
//   console.log(`Externally triggering activation for ${controller.name}`);
//   controller.activate(controller, controller.parentController)
//     .catch(err => console.error("External activation failed:", err)); // Might log AUR0503
// }
```

## Debugging Tips

* Identify the `<ControllerName>` and the unexpected `<State>` from the error message.
* Set breakpoints at the beginning of the `Controller#activate` method in `templating/controller.ts` and in the component's own `activate` hook (if present). Inspect the `controller.state` at these points.
* Trace the call stack when the error occurs to see what triggered the activation attempt.
* Look for asynchronous operations within lifecycle hooks. Could a delayed callback be causing overlapping activation attempts?
* Search the codebase for any manual calls to `controller.activate` or direct manipulation of `controller.state`. These are potential culprits.
* If the issue seems related to routing or composition, examine the configuration and the sequence of navigations or view compositions leading to the error.

```
```
