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

  1. 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.
  2. Within a describe, ensure the strictDi call sits in a beforeEach that is declared before (and therefore runs before) any beforeEach that calls inject().
  3. 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

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


AI-assisted analysis of angular/angular.js@d8f77817eb (2026-08-21). Data as JSON: /api/errors/12dc3350fcfe565d. Report an issue: GitHub.