angular/angular-cli · error

Invalid builders.json, builders key not found.

Error message

Invalid builders.json, builders key not found.

What it means

addBuilderFromPackage() resolves the file named by the package's 'builders' field (typically builders.json) and expects a top-level 'builders' object mapping builder names to definitions. If that object is missing, the host throws this error.

Source

Thrown at packages/angular_devkit/architect/testing/testing-architect-host.ts:53

  ): void {
    this._builderImportMap.set(builderName, builder);
    this._builderMap.set(builderName, { builderName, description, optionSchema });
  }
  async addBuilderFromPackage(packageName: string): Promise<void> {
    const packageJson = await import(packageName + '/package.json');
    if (!('builders' in packageJson)) {
      throw new Error('Invalid package.json, builders key not found.');
    }

    if (!packageJson.name) {
      throw new Error('Invalid package name');
    }

    const builderJsonPath = packageName + '/' + packageJson['builders'];
    const builderJson = await import(builderJsonPath);
    const builders = builderJson['builders'];
    if (!builders) {
      throw new Error('Invalid builders.json, builders key not found.');
    }

    for (const builderName of Object.keys(builders)) {
      const b = builders[builderName];
      // TODO: remove this check as v1 is not supported anymore.
      if (!b.implementation) {
        continue;
      }
      const handler = (await import(builderJsonPath + '/../' + b.implementation)).default;
      const optionsSchema = await import(builderJsonPath + '/../' + b.schema);
      this.addBuilder(`${packageJson.name}:${builderName}`, handler, b.description, optionsSchema);
    }
  }
  addTarget(target: Target, builderName: string, options: json.JsonObject = {}): void {
    this._targetMap.set(targetStringFromTarget(target), { builderName, options });
  }

  async getBuilderNameForTarget(target: Target): Promise<string | null> {

View on GitHub (pinned to bb72145f9a)

Solutions

  1. Ensure builders.json has shape { "builders": { "name": { "implementation": "...", "schema": "...", "description": "..." } } }.
  2. Check that package.json's 'builders' field points to the correct JSON file path.
  3. Fix typos in the top-level key (must be exactly 'builders').

Example fix

// before (builders.json)
{
  "my-builder": { "implementation": "./my-builder.impl" }
}
// after
{
  "builders": {
    "my-builder": { "implementation": "./my-builder.impl", "schema": "./schema.json", "description": "My builder" }
  }
}
Defensive patterns

Strategy: validation

Validate before calling

const pkg = require(packageName + '/package.json');
const builderJson = require(packageName + '/' + pkg.builders);
if (!builderJson.builders || typeof builderJson.builders !== 'object') {
  throw new Error(`${packageName}: builders.json lacks top-level builders object`);
}
await architectHost.addBuilderFromPackage(packageName);

Type guard

function isValidBuildersJson(json: unknown): json is { builders: Record<string, unknown> } {
  return typeof json === 'object' && json !== null &&
    'builders' in json && typeof (json as any).builders === 'object';
}

Try / catch

try {
  await architectHost.addBuilderFromPackage(packageName);
} catch (e) {
  if (e.message.includes('Invalid builders.json')) {
    throw new Error(`Fix ${packageName}/builders.json: must contain a "builders" object`);
  }
  throw e;
}

Prevention

When it happens

Trigger: The package's builders file (packageJson['builders'] path) exists but does not contain a top-level { "builders": { ... } } object — e.g. an empty file, wrong file, or a schema mismatched with the architect builder format.

Common situations: builders.json accidentally emptied or overwritten; pointing the 'builders' key at a different JSON file; hand-written builders.json using the wrong nesting shape.

Related errors


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