AUR0771

Error Message

AUR0771: The aurelia instance must be fully stopped before it can be disposed

Description

This error occurs when the aurelia.dispose() method is called on an Aurelia instance that is still considered 'started' or 'running'. Before an Aurelia instance's container and associated resources can be disposed of, the application must be explicitly stopped using the aurelia.stop() method. The stop() method handles the graceful deactivation and detachment of the root component.

Cause

The primary cause is calling aurelia.dispose() without first calling await aurelia.stop() (or handling the promise appropriately) on the same instance. Common scenarios include:

  1. Missing stop() call: Forgetting to stop the application before attempting to dispose of it.

  2. Incorrect Order: Calling dispose() immediately after stop() without waiting for the asynchronous stop() operation to complete.

  3. Calling dispose() on an instance that was never started: While less common, attempting to dispose of an instance that hasn't successfully completed the start() and subsequent stop() sequence might lead to unexpected states, potentially triggering this error if internal state flags are inconsistent.

Solution

  1. Call stop() Before dispose(): Always ensure that aurelia.stop() is called and awaited (or its promise handled) before calling aurelia.dispose().

  2. Await stop(): Since stop() is asynchronous, use await aurelia.stop() or chain dispose() in the .then() callback of the promise returned by stop().

Example

// main.ts (or relevant lifecycle management code)
import Aurelia from 'aurelia';
import { MyApp } from './my-app';

const host = document.querySelector('#app');

async function manageAppLifecycle() {
  const aurelia = new Aurelia();

  // Start the app
  await aurelia
    .app({ host, component: MyApp })
    .start();
  console.log('App started.');

  // ... application runs ...

  // Incorrect: Calling dispose() before stop()
  try {
    // aurelia.dispose(); // This would throw AUR0771
  } catch(e) {
    console.error("Incorrect dispose call:", e.message);
  }

  // Correct: Stop the app first, then dispose
  console.log('Stopping app...');
  await aurelia.stop(); // Wait for stop() to complete
  console.log('App stopped.');

  console.log('Disposing app instance...');
  aurelia.dispose(); // Now safe to call dispose()
  console.log('App disposed.');
}

manageAppLifecycle().catch(console.error);

// Example with .then()
const aureliaInstance = new Aurelia();
aureliaInstance.app({ host, component: MyApp })
  .start()
  .then(() => {
    console.log('App started (.then)');
    // ... run app ...
    console.log('Stopping app (.then)...');
    return aureliaInstance.stop(); // Return the promise from stop()
  })
  .then(() => {
    console.log('App stopped (.then).');
    console.log('Disposing app instance (.then)...');
    aureliaInstance.dispose(); // Safe to call dispose here
    console.log('App disposed (.then).');
  })
  .catch(err => console.error("Lifecycle error:", err));

Debugging Tips

  • Review the shutdown sequence of your Aurelia application.

  • Ensure that stop() is called before dispose().

  • Verify that you are waiting for the stop() promise to resolve before proceeding to dispose(). Use await or .then().

  • Check if multiple parts of your code might be attempting to stop or dispose of the same Aurelia instance concurrently, leading to race conditions.

Last updated

Was this helpful?