angular/angular-cli · error

Package "${packageName}" has an invalid builder implementati

Error message

Package "${packageName}" has an invalid builder implementation path: "${builderName}" --> "${builder.implementation}"

What it means

The builder's implementation path must be relative and stay within the package. resolveBuilder throws when the manifest entry's 'implementation' value is absolute or starts with '..'.

Source

Thrown at packages/angular_devkit/architect/node/node-modules-architect-host.ts:196

      throw new Error(`Cannot find builder ${JSON.stringify(builderStr)}.`);
    }

    // Resolve alias reference if entry is a string
    if (typeof builder === 'string') {
      return this.resolveBuilder(
        builder,
        path.dirname(packageJsonPath),
        (seenBuilders ?? new Set()).add(builderStr),
      );
    }

    // Determine builder implementation path (relative within package only)
    const implementationPath = builder.implementation && path.normalize(builder.implementation);
    if (!implementationPath) {
      throw new Error('Could not find the implementation for builder ' + builderStr);
    }
    if (path.isAbsolute(implementationPath) || implementationPath.startsWith('..')) {
      throw new Error(
        `Package "${packageName}" has an invalid builder implementation path: "${builderName}" --> "${builder.implementation}"`,
      );
    }

    // Determine builder option schema path (relative within package only)
    let schemaPath = builder.schema;
    if (!schemaPath) {
      throw new Error('Could not find the schema for builder ' + builderStr);
    }
    if (path.isAbsolute(schemaPath) || path.normalize(schemaPath).startsWith('..')) {
      throw new Error(
        `Package "${packageName}" has an invalid builder schema path: "${builderName}" --> "${builder.schema}"`,
      );
    }

    // The file could be either a package reference or in the local manifest directory.
    if (schemaPath.startsWith('.')) {
      schemaPath = path.join(buildersManifestDirectory, schemaPath);

View on GitHub (pinned to bb72145f9a)

Solutions

  1. Place the implementation inside the package and set a relative path like './impl.js'.
  2. Copy shared implementation files into the package at build time (bundle them).
  3. Rebuild/republish the manifest with normalized relative paths.

Example fix

// before (builders.json)
"implementation": "../shared/impl.js"
// after
"implementation": "./impl.js"
Defensive patterns

Strategy: validation

Validate before calling

const impl = require(`${packageName}/builders.json`).builders?.[builderName]?.implementation;
if (impl && (path.isAbsolute(impl) || impl.startsWith('..'))) throw new Error(`Invalid implementation path: ${impl}`);

Try / catch

try { await host.resolveBuilder(builderStr); } catch (e) { if (String(e.message).includes('invalid builder implementation path')) { /* make the implementation path relative and inside the package */ } else throw e; }

Prevention

When it happens

Trigger: builders.json entry with "implementation": "/abs/path/impl.js" or "../other/impl.js"; monorepo setups sharing implementation files across packages.

Common situations: Custom builder packages reaching into sibling directories; hand-crafted manifests with machine-specific absolute paths; publishing packages built with paths meant only for local dev.

Related errors


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