angular/angular.js · error · Error
Injector already created, can not register a module!
Error message
Injector already created, can not register a module!
What it means
angular.mock.module(...) (window.module) only QUEUES module registrations; the queue is consumed when the injector is first created for the current spec. Its workFn runs at injector-creation time, and if currentSpec.$injector is already set — inject() has already run for this spec — no further modules can be registered, so it throws 'Injector already created, can not register a module!'.
Source
Thrown at src/ngMock/angular-mocks.js:3091
* This function registers a module configuration code. It collects the configuration information
* which will be used when the injector is created by {@link angular.mock.inject inject}.
*
* See {@link angular.mock.inject inject} for usage example
*
* @param {...(string|Function|Object)} fns any number of modules which are represented as string
* aliases or as anonymous module initialization functions. The modules are used to
* configure the injector. The 'ng' and 'ngMock' modules are automatically loaded. If an
* object literal is passed each key-value pair will be registered on the module via
* {@link auto.$provide $provide}.value, the key being the string name (or token) to associate
* with the value on the injector.
*/
var module = window.module = angular.mock.module = function() {
var moduleFns = Array.prototype.slice.call(arguments, 0);
return wasInjectorCreated() ? workFn() : workFn;
/////////////////////
function workFn() {
if (currentSpec.$injector) {
throw new Error('Injector already created, can not register a module!');
} else {
var fn, modules = currentSpec.$modules || (currentSpec.$modules = []);
angular.forEach(moduleFns, function(module) {
if (angular.isObject(module) && !angular.isArray(module)) {
fn = ['$provide', function($provide) {
angular.forEach(module, function(value, key) {
$provide.value(key, value);
});
}];
} else {
fn = module;
}
if (currentSpec.$providerInjector) {
currentSpec.$providerInjector.invoke(fn);
} else {
modules.push(fn);
}
});View on GitHub (pinned to d8f77817eb)
Solutions
- Declare ALL modules before anything injects: put beforeEach(module('a', 'b')) physically before any beforeEach that uses inject().
- Inside a single it(), order it module(...) first, then inject(...) — never inject then module.
- For per-test variation, register one parameterized module in the outer setup whose config reads a mutable flag/variable the test sets before inject() creates the injector.
Example fix
// before
var $httpBackend;
beforeEach(inject(function(_$httpBackend_) {
$httpBackend = _$httpBackend_; // injector created here
}));
beforeEach(module('mock.responses')); // throws: injector already created
// after
beforeEach(module('mock.responses')); // register modules FIRST
beforeEach(inject(function(_$httpBackend_) {
$httpBackend = _$httpBackend_;
})); Defensive patterns
Strategy: validation
Validate before calling
// Enforce ordering in shared setup: all module() calls before any inject()
beforeEach(module('app', 'app.templates', 'test.stubs'));
// only AFTER the module hooks:
beforeEach(inject(function(_$httpBackend_) { /* ... */ })); Try / catch
// Fail with actionable guidance when module() is called too late
try {
module('late.module');
} catch (e) {
if (/Injector already created/.test(e.message)) {
throw new Error('Move this module() into a beforeEach that runs before any inject()');
}
throw e;
} Prevention
- Keep the lifecycle rule: module() (and inject.strictDi) before inject(), always in hook order.
- For per-test overrides, register a flag-driven config function early and set the flag per test.
- Never call module() inside it() after fixtures were injected.
When it happens
Trigger: Calling module(...) inside an it() after an inject() has run; calling module(...) inside a function passed to inject(); a beforeEach(module(...)) declared after another beforeEach whose function already called inject(); a lazy helper that registers modules on first use, triggered mid-test.
Common situations: Mixing module() and inject() in the same spec in the wrong order; trying to register a per-test override module after the injectable fixtures were created; Jasmine beforeAll-style shared setup that injects, followed by per-test module() calls; the module() call is deferred (returned function) and invoked too late.
Related errors
- Injector already created, can not modify strict annotations
- No component found
- Too many components found
- No deferred tasks to be flushed
- Deferred tasks to flush ({}): {}
AI-assisted analysis of angular/angular.js@d8f77817eb (2026-08-21).
Data as JSON: /api/errors/3fd88a228aa23c88.
Report an issue: GitHub.