- Angular
NullInjectorError No provider forの直し方|原因一覧
NullInjectorError: No provider for X! は、inject(X)(またはコンストラクタ引数)で X を受け取ろうとしたのに、どこにも X の「提供元(provider)」が登録されていなかったときのエラーです。 Angular の依存性注入(DI:部品が必要なものを外から受け取るしくみ)は、近い場所から順に provider を探し、最後まで見つからないと、このエラーを出します。
Angular v20 からは文面が変わり、v22.2.2 では次のように出ました。
ERROR ɵNotFound: NG0201: No provider found for `_CartStore`. Source: Environment Injector. Path: _OrderService -> _CartStore. Find more at https://v22.angular.dev/errors/NG0201
直し方は、エラーに出た名前(上の例では CartStore)を、使う場所から見える位置で provide することです。 名前ごとの主な原因は次のとおりです。
| エラーに出る名前 | 主な原因 | 対処 |
|---|---|---|
_HttpClient |
v20 までで provideHttpClient() が無い |
provideHttpClient() を追加。v21 以降は無くても注入できた |
HttpTestingController |
テストで provideHttpClientTesting() が無い |
provideHttpClient() と provideHttpClientTesting() を TestBed に追加 |
ActivatedRoute |
provideRouter() が無い(テストで多い) |
provideRouter([]) を追加 |
| 自作サービス | @Injectable() だけで providedIn が無い |
@Injectable({ providedIn: 'root' }) か @Service() |
| 自作サービス | 子・別ルートの providers にしか無い |
使う場所の上(親・アプリ全体)で provide |
InjectionToken XXX |
トークンを作っただけで値を登録していない | { provide: XXX, useValue: … } か factory |
確認環境:Angular 22.2.2(@angular/core・@angular/common・@angular/router)、Node.js 24.15.0(Linux)。ng new のプロジェクトで、TestBed+Vitest 5.0.4 と、ng build した画面を Chromium(Playwright 1.56.1)で開いて再現しました。v19〜v21 の文面は、npm の @angular/core 19.2.25・20.3.33・21.2.25 の配布コードで確かめました(確認日 2026年10月12日)。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「NullInjectorError No provider forの直し方|原因一覧」
エラー文の読み方(v22 と v19 までの違い)
v20 以降(v22.2.2 で出た文面)
NG0201: No provider found for `_CartStore`. Source: Environment Injector. Path: _OrderService -> _CartStore.
| 部分 | 意味 |
|---|---|
No provider found for `_CartStore` |
見つからなかったもの。先頭の _ は開発ビルドでクラス名に付いたもので、ソースでは CartStore |
Source: Environment Injector |
探し始めた場所。アプリ全体の injector(providedIn: 'root' などが入る場所) |
Source: DynamicTestModule |
TestBed のテスト用の injector |
Path: _OrderService -> _CartStore |
依存のつながり。OrderService を作ろうとして、その中の CartStore が見つからなかった |
v19 まで(検索で多く見る文面)
v19.2.25 の配布コードでは、エラーは NullInjectorError という名前で、次の形の文面を組み立てていました(R3InjectorError(…) の括弧の中は injector の名前、[ ] の中は依存のつながりです)。
NullInjectorError: R3InjectorError(Environment Injector)[_OrderService -> _CartStore]:
NullInjectorError: No provider for _CartStore!
v20.3.33・v21.2.25 の配布コードでは、v22 と同じ No provider found for の文面でした。検索するときは、v20 以降なら「NG0201」、v19 までなら「NullInjectorError: No provider for」で探すと、同じエラーの情報に当たります。 原因と直し方は同じです。
本番ビルドでは名前が出ない
同じ画面を本番ビルド(ng build)で開くと、コンソールには次だけが出ました。
ERROR v: NG0201
at Nt.get (http://localhost:4302/main-QOVZIITG.js:4:6356)
何が足りないかは出ないので、開発ビルド(ng serve)で同じ操作をして、名前を確かめます。
standalone 構成での provide の置き場所
v22 の ng new は standalone 構成(NgModule を使わない形)です。provide できる場所と、そこに置いたものが見える範囲は次のとおりです。
| 置き場所 | 書き方 | 見える範囲 |
|---|---|---|
| サービス自身 | @Injectable({ providedIn: 'root' })・@Service() |
アプリ全体(1つを共有) |
| アプリの起動設定 | app.config.ts の providers(bootstrapApplication に渡る) |
アプリ全体 |
| ルート | ルート定義の providers: [...] |
そのルートと子ルートの部品・ガード・リゾルバー |
| コンポーネント | @Component({ providers: [...] }) |
そのコンポーネントと、テンプレートの中の子孫 |
// src/app/app.config.ts(bootstrapApplication(App, appConfig) に渡る)
export const appConfig: ApplicationConfig = {
providers: [
provideBrowserGlobalErrorListeners(),
provideRouter(routes),
provideHttpClient(withInterceptors([authInterceptor])),
{ provide: API_URL, useValue: 'https://api.example.com' },
],
};
@Service() は v22 で使えるデコレーターで、angular.dev では @Injectable({ providedIn: 'root' }) の短い書き方と説明されています。 inject() で受け取る前提で、コンストラクタ引数での注入や useClass などには対応しません。@Service({ autoProvided: false }) にすると自動では登録されず、providers に書く必要があります(書き忘れると NG0201 でした)。サービスの作り方は関連記事「Angularサービスと依存性注入|injectとconstructorの違い」で扱っています。
名前別:原因と直し方(実際のエラー文つき)
_HttpClient:v21 からは provideHttpClient() 無しでも注入できた
v22.2.2 では、provideHttpClient() を書かずに inject(HttpClient) しても、エラーになりませんでした。 angular.dev の HttpClient のセットアップの説明にも「HttpClient is available for injection by default in Angular v21 and later.」とあり、配布コードでも HttpClient が providedIn: 'root' になっていました。
v20 までのプロジェクトで No provider for _HttpClient が出るときは、app.config.ts に provideHttpClient() を追加します(NgModule 構成なら AppModule の providers)。v21 以降でも、インターセプターや XSRF の設定をするときは provideHttpClient(withInterceptors([...])) のように書きます。HttpClient の使い方は関連記事「Angular HttpClientの使い方|GET・POSTとエラー処理」、インターセプターは関連記事「Angularインターセプターの使い方|トークン付与とエラー共通処理」で扱っています。
ActivatedRoute:provideRouter() が無い
NG0201: No provider found for `ActivatedRoute`. Source: DynamicTestModule.
テストで、ActivatedRoute を使うコンポーネントを作ったときに出ました。Router は v22.2.2 では provideRouter() 無しでも注入できましたが、ActivatedRoute はできませんでした。 TestBed に provideRouter([]) を足すと消えました。アプリでは app.config.ts の provideRouter(routes) が入っているかを見ます。ルーティングの設定は関連記事「Angularルーティング設定|provideRouter・パラメータ・404」で扱っています。
自作サービス①:providedIn が無い
@Injectable() // ← providedIn が無い
export class NoRootService {}
NG0201: No provider found for `_NoRootService`. Source: DynamicTestModule.
@Injectable() は「DI で作れるクラス」という印で、それだけでは登録されません。@Injectable({ providedIn: 'root' }) にするか、使う場所の providers に書きます。
自作サービス②:子の providers にあるものを親で使う
@Component({ selector: 'app-cart', template: ``, providers: [CartStore] })
export class CartView {}
@Component({ selector: 'app-page', imports: [CartView], template: `<app-cart />` })
export class Page {
store = inject(CartStore); // ← 子にしか無いので見つからない
}
NG0201: No provider found for `_CartStore`. Source: DynamicTestModule.
DI は、自分 → 親 → さらに親 → アプリ全体、と上に向かって探します。子や兄弟の providers は見に行きません。 共有したいなら、使う部品の共通の親か、アプリ全体で provide します。
自作サービス③:root のサービスが、コンポーネントの providers のものを使う
@Injectable({ providedIn: 'root' })
export class OrderService { cart = inject(CartStore); }
@Component({ selector: 'order-page', template: `<p>注文</p>`, providers: [CartStore] })
export class OrderPage { order = inject(OrderService); }
ERROR ɵNotFound: NG0201: No provider found for `_CartStore`. Source: Environment Injector. Path: _OrderService -> _CartStore.
OrderPage には CartStore がありますが、OrderService はアプリ全体の injector で作られるので、そこから見えるものしか受け取れません。 Path: に2つ以上の名前が並ぶときは、このパターンを疑います。CartStore も providedIn: 'root' にするか、OrderService を OrderPage の providers に移します。
自作サービス④:ルートの providers にあるものを、ルートの外で使う
provideRouter([{ path: 'admin', providers: [AdminStore], component: AdminPage }])
/admin の AdminPage からは使えましたが、ルートの外にあるヘッダー部品から inject(AdminStore) すると、No provider found for `_AdminStore` になりました。angular.dev でも、ルートの providers は、そのルートの部品・ガード・リゾルバーから使える範囲と説明されています。遅延ロードのルートに provide するときも、この範囲を意識します。遅延ロードは関連記事「Angular遅延ロード|loadComponentとloadChildren」で扱っています。
InjectionToken:値を登録していない
export const API_URL = new InjectionToken<string>('API_URL');
// どこにも { provide: API_URL, ... } が無い
NG0201: No provider found for `InjectionToken API_URL`. Source: Environment Injector.
InjectionToken(クラス以外の値を DI で渡すための鍵)は、作っただけでは値がありません。次のどちらかで値を登録します。
// ① 起動設定で値を渡す
{ provide: API_URL, useValue: 'https://api.example.com' }
// ② トークンに既定の値を持たせる(providedIn: 'root' 扱いになる)
export const API_URL = new InjectionToken<string>('API_URL', { factory: () => '/api' });
②の形にすると、何も登録しなくても /api が入りました。環境ごとに値を変える方法は、関連記事「Angular environmentで環境変数を切り替える設定手順」で扱っています。
無いかもしれないものを受け取る:optional
const url = inject(API_URL, { optional: true }); // 無ければ null
登録が無い状態で試すと、エラーにならず null が返りました。「設定されていれば使う」値に使えます。
テスト(TestBed)で出るとき
テストでは app.config.ts は読み込まれないので、アプリで provide しているものも、TestBed に書く必要があります。
| エラーに出る名前 | TestBed の providers に足すもの |
|---|---|
HttpTestingController |
provideHttpClient(), provideHttpClientTesting()(この順) |
ActivatedRoute |
provideRouter([]) |
| 自作サービス(本物を使わない) | { provide: UserApi, useValue: fakeUserApi } |
InjectionToken XXX |
{ provide: XXX, useValue: … } |
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
provideHttpClient(),
provideHttpClientTesting(), // provideHttpClient() の後に書く
provideRouter([]),
{ provide: API_URL, useValue: '/test-api' },
],
});
});
angular.dev では、provideHttpClientTesting() が provideHttpClient() の一部を上書きするため、この順に書くと説明されています。HttpTestingController を provideHttpClientTesting() 無しで取り出すと、No provider found for `HttpTestingController` になりました。テストの書き方は関連記事「Angular テスト Vitest 入門|v22の書き方・移行・実行結果つき」で扱っています。
よくある質問
Q. @Injectable({ providedIn: 'root' }) にしてあるのに出ます。
A. Path: を見ます。_A -> _B なら、足りないのは A ではなく B です。A の中で inject(B) している B のほうに provider がありません。
Q. コンポーネントの imports に入れれば使えますか。
A. imports は、テンプレートで使う部品・ディレクティブ・パイプを並べる場所です。サービスは imports ではなく providers か providedIn で登録します。コンポーネントの基本は関連記事「Angularコンポーネントの作り方|standaloneとimportsの基本」で扱っています。
Q. ライブラリのサービスで出ます。
A. 多くのライブラリは provideXxx() という関数を用意していて、app.config.ts の providers に入れる形です。ライブラリの導入手順に書かれている provide の関数が入っているかを見ます。
Q. 同じサービスが2つできてしまいます。
A. providedIn: 'root' のサービスを、コンポーネントの providers にも書くと、その部品の下では別のインスタンスになります。アプリ全体で1つにしたいなら、providers からは外します。
まとめ
NullInjectorError: No provider for X(v19 まで)とNG0201: No provider found for X(v20 以降)は同じエラー。X の provider が、使う場所から見える位置に無いPath: A -> Bなら足りないのは B。Sourceで探し始めた場所が分かる- DI は 自分から上へ 探す。子・兄弟・別ルートの
providersは見えない - v21 以降、HttpClient は
provideHttpClient()無しでも注入できた。ActivatedRouteはprovideRouter()が要った - テストでは
app.config.tsの providers は効かない。TestBed に書く
参考・出典
確認日はいずれも 2026年10月12日です。
- Angular「NG0201: No Provider Found」:https://angular.dev/errors/NG0201
- Angular「Defining dependency providers」:https://angular.dev/guide/di/defining-dependency-providers
- Angular「Creating and using services」:https://angular.dev/guide/di/creating-and-using-services
- Angular「Setting up HttpClient」:https://angular.dev/guide/http/setup
- Angular「Testing requests」:https://angular.dev/guide/http/testing
- TechOverflow「How to fix Angular NullInjectorError: No provider for HttpClient」:https://www.techoverflow.net/2023/01/23/how-to-fix-angular-nullinjectorerror-no-provider-for-httpclient
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「NullInjectorError No provider forの直し方|原因一覧」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。