Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

Angular’s NG0205 means code tried to retrieve a service from an injector after Angular had destroyed it. The usual cause is work—such as a timer callback, promise continuation, or subscription—that runs after its component or other owning scope has ended. Find the access in the stack trace, then either stop that work when its owner is destroyed or move it to a scope that should remain alive.

What NG0205 means

Angular describes NG0205 as an attempt to retrieve a service from an injector that has already been destroyed. An injector can be destroyed along with the component, directive, or module whose lifecycle owns it. Any later code that tries to obtain a service through that injector can trigger the error. See Angular’s NG0205 error reference.

This is a lifecycle and dependency-injection timing problem, not the same as an ordinary missing provider. The key question is: what code tried to use the injector, and why was it still running after its owner ended?

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How to find the code that outlived its owner

  1. Start at the stack trace. Angular says the trace points to where the destroyed injector was accessed. Identify the service lookup or operation at that location.
  2. Trace back to the work that led there. Look for a timer or other delayed callback, a promise continuation, an Observable subscription, or cleanup code. Follow the callback’s path to the injector access.
  3. Check what could have destroyed the owner first. Navigation or conditional rendering may remove a component while delayed work is still pending. Angular’s example uses a timeout that can fire after destruction.
  4. Inspect teardown ordering. Cleanup can itself cause the error if it tries to retrieve a service from an injector that is already being torn down. Avoid relying on a late injector lookup to perform cleanup.

Angular recommends retaining service references on the class rather than trying to obtain them from an injector later in asynchronous code. Capture the dependency while Angular constructs the class—for example, in an injected field—and use that reference in the callback.

Stop work when its lifecycle owner is destroyed

Choose the cleanup mechanism based on the kind of work and the scope that owns it.

For an RxJS Observable subscription

Use takeUntilDestroyed when a subscription should complete as soon as its Angular context is destroyed. Without an argument, it uses the current DestroyRef; if you call it outside an injection context, pass the intended reference explicitly. Angular documents the API as stable since v19.0, so check the version used by your project. See the takeUntilDestroyed API reference.

import { takeUntilDestroyed } from '@angular/core/rxjs-interop';

this.dataStream
  .pipe(takeUntilDestroyed())
  .subscribe(value => this.updateView(value));

When setting up a subscription outside an injection context, inject or otherwise retain the appropriate DestroyRef and pass it to takeUntilDestroyed(destroyRef). That makes the intended lifecycle owner explicit.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For other cleanup callbacks

Use DestroyRef.onDestroy(callback) to register general cleanup with an Angular lifecycle scope. It returns a function that unregisters the callback if it is no longer needed. The reference’s destroyed property reports whether its associated instance has been destroyed. See Angular’s DestroyRef API reference.

import { DestroyRef, inject } from '@angular/core';

export class ExampleComponent {
  private readonly destroyRef = inject(DestroyRef);

  constructor() {
    const timer = setTimeout(() => this.refresh(), 5000);
    this.destroyRef.onDestroy(() => clearTimeout(timer));
  }

  private refresh() {
    // Work that belongs to this component
  }
}

Here, clearing the timer prevents its callback from firing after the component’s scope ends. For asynchronous work that cannot be cancelled, check the relevant reference’s destroyed state before acting, and avoid looking up dependencies from a scope that no longer exists.

Choose the scope that should own the work

A DestroyRef follows the lifecycle scope where it is injected: for a component or directive, it follows that instance; otherwise, it follows the corresponding injector. Tie cleanup to the scope that actually owns the work. A view-specific subscription generally belongs to its component, while work intended to continue after that view disappears needs an owner that also remains alive.

If a callback legitimately needs to outlive a component, move the work and its dependencies to a longer-lived service or injector rather than letting a component-owned callback reach back into a destroyed injector. Angular’s DestroyableInjector API reference describes an injector its owner can destroy, which triggers its DestroyRef destroy hooks. A broader scope is not automatically the right choice: use it only when the work should genuinely share that longer lifetime.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

NG0205 versus NG0203

These errors describe different problems. NG0203 concerns calling inject() outside an injection context. Angular limits inject() to specific contexts, such as class construction and factory execution, and warns against calling it from lifecycle hooks including ngOnInit, ngAfterViewInit, and ngOnDestroy. NG0205 instead means an injector was already destroyed when code tried to retrieve a service. Similar lifecycle code can expose either issue, so diagnose the actual failing operation and error rather than treating the codes as synonyms.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.