angular/angular-cli · error · SchematicMissingFactoryException

Schematic ${JSON.stringify(name)} is missing a factory.

Error message

Schematic ${JSON.stringify(name)} is missing a factory.

What it means

Thrown by createSchematicDescription when the schematic entry in collection.json has no `factory` property. A schematic must point to a factory function; without one the engine cannot instantiate it.

Source

Thrown at packages/angular_devkit/schematics/tools/file-system-engine-host-base.ts:238

    if (partialDesc.extends) {
      const index = partialDesc.extends.indexOf(':');
      const collectionName = index !== -1 ? partialDesc.extends.slice(0, index) : null;
      const schematicName =
        index === -1 ? partialDesc.extends : partialDesc.extends.slice(index + 1);

      if (collectionName !== null) {
        const extendCollection = this.createCollectionDescription(collectionName);

        return this.createSchematicDescription(schematicName, extendCollection);
      } else {
        return this.createSchematicDescription(schematicName, collection);
      }
    }
    // Use any on this ref as we don't have the OptionT here, but we don't need it (we only need
    // the path).
    if (!partialDesc.factory) {
      throw new SchematicMissingFactoryException(name);
    }
    const resolvedRef = this._resolveReferenceString(
      partialDesc.factory,
      collectionPath,
      collection,
    );
    if (!resolvedRef) {
      throw new FactoryCannotBeResolvedException(name);
    }

    let schema = partialDesc.schema;
    let schemaJson: JsonObject | undefined = undefined;
    if (schema) {
      if (!isAbsolute(schema)) {
        schema = join(collectionPath, schema);
      }
      schemaJson = readJsonFile(schema) as JsonObject;
    }

View on GitHub (pinned to bb72145f9a)

Solutions

  1. Open collection.json and add the missing `factory` field pointing to the compiled JS file and export, e.g. "./component/index#myComponentGenerator".
  2. Verify the path/export exists relative to the collection root and is compiled if written in TypeScript.
  3. Reload the collection to confirm.

Example fix

// before (collection.json)
"my-schematic": { "description": "does stuff", "schema": "./schema.json" }
// after
"my-schematic": { "factory": "./my-schematic/index#mySchematic", "description": "does stuff", "schema": "./schema.json" }
Defensive patterns

Strategy: validation

Validate before calling

const coll = JSON.parse(readFileSync('collection.json', 'utf8'));
for (const [name, s] of Object.entries(coll.schematics)) {
  if (!s.factory) throw new Error(`Schematic '${name}' has no factory`);
}

Type guard

function hasFactory(s: unknown): s is { factory: string } {
  return typeof s === 'object' && s !== null && typeof (s as any).factory === 'string' && (s as any).factory.length > 0;
}

Try / catch

try {
  return engine.createSchematic(name, collection);
} catch (e) {
  if (String(e.message).includes('is missing a factory')) {
    throw new Error(`Add a "factory" field to schematic '${name}' in collection.json`);
  }
  throw e;
}

Prevention

When it happens

Trigger: A collection.json schematic entry omits `factory` (or it is null/undefined), so `if (!partialDesc.factory)` fires after resolving aliases/references.

Common situations: Hand-writing a custom collection and forgetting the factory field; a typo like `factories` or `factoryFn` in collection.json; a schematic entry that only sets aliases/schema; upgrading from a generator whose collection format differed.

Related errors


AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30). Data as JSON: /api/errors/6bd36d843c992ec6. Report an issue: GitHub.