angular/angular.js · error · Error
Injector already created, can not modify strict annotations
Error message
Injector already created, can not modify strict annotations
What it means
angular.mock.inject.strictDi(value) toggles strict dependency-injection annotation for injectors created afterwards (catching services relying on implicit annotations). The setting is baked into the injector at creation time, so attempting to change it once currentSpec.$injector exists throws 'Injector already created, can not modify strict annotations'. Note it only throws when the value actually differs from the current setting.
Source
Thrown at src/ngMock/angular-mocks.js:3426
throw new ErrorAddingDeclarationLocationStack(e, errorForStack);
}
throw e;
} finally {
errorForStack = null;
}
}
}
};
angular.mock.inject.strictDi = function(value) {
value = arguments.length ? !!value : true;
return wasInjectorCreated() ? workFn() : workFn;
function workFn() {
if (value !== currentSpec.$injectorStrict) {
if (currentSpec.$injector) {
throw new Error('Injector already created, can not modify strict annotations');
} else {
currentSpec.$injectorStrict = value;
}
}
}
};
function InjectorState() {
this.shared = false;
this.sharedError = null;
this.cleanupAfterEach = function() {
return !this.shared || this.sharedError;
};
}
})(window.jasmine || window.mocha);
View on GitHub (pinned to d8f77817eb)
Solutions
- Set it globally and early: angular.mock.inject.strictDi(true) in a top-level/global beforeEach in a shared karma setup file, before any module/inject runs.
- Within a describe, ensure the strictDi call sits in a beforeEach that is declared before (and therefore runs before) any beforeEach that calls inject().
- Keep it consistent across the suite — flipping it per-test requires isolated injector creation ordering that Jasmine hooks make fragile.
Example fix
// before
describe('svc', function() {
beforeEach(inject(function(mySvc) { /* injector created here */ }));
beforeEach(function() {
angular.mock.inject.strictDi(true); // throws: injector already created
});
});
// after
// karma-global setup (runs first)
beforeEach(function() {
angular.mock.inject.strictDi(true);
});
describe('svc', function() {
beforeEach(inject(function(mySvc) { /* now strict-di applies */ }));
}); Defensive patterns
Strategy: validation
Validate before calling
// Set strict-di once, globally, before anything injects
// (e.g., in a karma-shared setup file)
beforeEach(function() {
angular.mock.inject.strictDi(true);
});
// ...only then, in suites:
beforeEach(module('app'));
beforeEach(inject(function(mySvc) { /* strict-di applies here */ })); Prevention
- Set strictDi in the outermost (globally first) beforeEach, never per-test.
- Keep the strictDi value uniform across the suite; flipping it mid-lifecycle is what throws.
- Annotate all services (ng-annotate / explicit $inject) so strict mode passes.
When it happens
Trigger: Calling inject.strictDi(true) inside an it() or beforeEach that runs after another beforeEach already called inject(); enabling strictDi lazily to check one service after fixtures were injected; disabling (strictDi(false)) in a nested describe after the parent setup injected with strict mode on.
Common situations: Adding strict-di verification to an existing suite whose beforeEach already creates injectables; calling inject.strictDi after module() setup was consumed by an inject() in the same file's earlier hook; migration checks for minification safety (implicit annotations) run too late in the lifecycle.
Related errors
- Injector already created, can not register a module!
- 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/12dc3350fcfe565d.
Report an issue: GitHub.