angular/angular-cli · error · SchematicEngineConflictingException
A schematic was called from a different engine as its parent
Error message
A schematic was called from a different engine as its parent.
What it means
Each SchematicEngine instance owns its own collection/schematic registries and task schedulers. When creating an execution context for a schematic, if the supplied parent context carries an "engine" reference that is a different engine instance than the one being asked to create the context, the parent-child relationship is invalid, so SchematicEngineConflictingException is thrown. The engine refuses to mix contexts across engine instances because task scheduling and merge strategies would otherwise be attributed to the wrong engine.
Source
Thrown at packages/angular_devkit/schematics/src/engine/engine.ts:248
description,
new Set(parentNames),
);
bases.unshift(base, ...baseBases);
}
}
return [description, bases];
}
createContext(
schematic: Schematic<CollectionT, SchematicT>,
parent?: Partial<TypedSchematicContext<CollectionT, SchematicT>>,
executionOptions?: Partial<ExecutionOptions>,
): TypedSchematicContext<CollectionT, SchematicT> {
// Check for inconsistencies.
if (parent && parent.engine && parent.engine !== this) {
throw new SchematicEngineConflictingException();
}
let interactive = true;
if (executionOptions && executionOptions.interactive != undefined) {
interactive = executionOptions.interactive;
} else if (parent && parent.interactive != undefined) {
interactive = parent.interactive;
}
let context: TypedSchematicContext<CollectionT, SchematicT> = {
debug: (parent && parent.debug) || false,
engine: this,
logger:
(parent && parent.logger && parent.logger.createChild(schematic.description.name)) ||
new logging.NullLogger(),
schematic,
strategy:
parent && parent.strategy !== undefined ? parent.strategy : this.defaultMergeStrategy,View on GitHub (pinned to bb72145f9a)
Solutions
- Invoke createContext on the same engine instance that owns the parent context (use parent.engine.createContext(...) instead of a different engine).
- Ensure a single SchematicEngine instance is created per execution and pass that one to all schematic/code invocations.
- If crossing engines is intentional, omit the "engine" field on the parent (pass a parent without engine) or don't pass a parent at all.
- In nested schematic calls, use the current context's engine (context.engine) rather than constructing a new engine.
Example fix
// before const otherEngine = new SchematicEngine(host); const ctx = otherEngine.createContext(schematic, parentContext); // parentContext.engine !== otherEngine // after const ctx = parentContext.engine.createContext(schematic, parentContext);
Defensive patterns
Strategy: validation
Validate before calling
function canUseAsParent(engine: SchematicEngine, parent?: Partial<TypedSchematicContext<any, any>>): boolean {
return !parent || !parent.engine || parent.engine === engine;
}
if (canUseAsParent(engine, parentContext)) {
engine.createContext(schematic, parentContext);
} Type guard
function belongsToEngine<T, C extends { engine?: unknown }>(engine: SchematicEngine<T, any>, ctx: C): ctx is C & { engine: SchematicEngine<T, any> } {
return ctx.engine === undefined || ctx.engine === engine;
} Try / catch
import { SchematicEngineConflictingException } from '@angular-devkit/schematics';
try {
const ctx = engine.createContext(schematic, parentContext);
} catch (e) {
if (e instanceof SchematicEngineConflictingException) {
const ctx = parentContext.engine.createContext(schematic, parentContext);
} else { throw e; }
} Prevention
- Create exactly one SchematicEngine per execution and thread it through your code instead of instantiating new engines ad hoc.
- When delegating to another engine, pass a parent without its engine field (or no parent) instead of the foreign context.
- In tests, build engine + host per fixture and never share captured contexts between engines.
When it happens
Trigger: Calling engine.createContext(schematic, parentContext) where parentContext.engine is set and !== the engine instance the method is invoked on — typically when schematic code captures a context from one engine (e.g. created by an external SchematicEngine) and passes it as parent to another engine's createContext, or when invoking a schematic through a second engine instance while passing the first engine's context along.
Common situations: Custom CLI or builder code that instantiates more than one SchematicEngine and shares contexts between them; library code that stores a global parent context and reuses it after a new engine was created (common in tests that build a fresh engine per test); running a schematic inside another schematic but through a separately constructed engine instead of engine.registry/context from the current context.
Related errors
- Unsupported schematic context. Expected a FileSystemSchemati
- schematicName cannot be undefined.
- The "not" keyword is not supported in JSON Schema.
- Could not find (/.angular.json)
- Unknown schematics built-in module '${id}' requested from sc
AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30).
Data as JSON: /api/errors/1a94f87f82e5f2a4.
Report an issue: GitHub.