angular/angular-cli · error · InvalidPipeException

Pipe "${pipe}" is invalid.

Error message

Pipe "${pipe}" is invalid.

What it means

Once a pipe is found in data, it must be a function; a non-function value under the pipe's key throws InvalidPipeException. This distinguishes 'pipe missing' (248) from 'pipe present but not callable'.

Source

Thrown at packages/angular_devkit/schematics/src/rules/template.ts:138

        if (typeof replacement == 'function') {
          replacement = replacement.call(data, original);
        }

        if (replacement === undefined) {
          throw new OptionIsNotDefinedException(name);
        }

        replacement = pipes.reduce((acc: string, pipe: string) => {
          if (!pipe) {
            return acc;
          }
          if (!(pipe in data)) {
            throw new UnknownPipeException(pipe);
          }
          const pipeFn = data[pipe];
          if (typeof pipeFn != 'function') {
            throw new InvalidPipeException(pipe);
          }

          // Coerce to string.
          return '' + pipeFn(acc);
        }, '' + replacement);
      }

      path = path.substring(0, start) + replacement + path.substring(end + ieL);

      start = path.indexOf(options.interpolationStart);
      // See above.
      end = path.indexOf(options.interpolationEnd, start + isL + 1);
    }

    return { path: normalize(path), content };
  };
}

View on GitHub (pinned to bb72145f9a)

Solutions

  1. Ensure the value bound to the pipe key is a function: (acc: string) => string.
  2. Rename conflicting keys so options data and pipe functions don't collide.
  3. Check the import — import the helper function, not a constant, e.g. `import { strings } from '@angular-devkit/core'` then strings.dasherize.

Example fix

// before
applyTemplates({ dasherize: options.dasherize }) // boolean
// after
applyTemplates({ dasherize: (s: string) => strings.dasherize(s) })
Defensive patterns

Strategy: validation

Validate before calling

if (typeof data[pipe] !== 'function') {
  throw new Error(`Template pipe "${pipe}" must be a (string) => string function`);
}

Type guard

function isPipeFunction(v: unknown): v is (acc: string) => string {
  return typeof v === 'function';
}

Try / catch

try {
  return mergeWith(apply(source, [template(options)]));
} catch (err) {
  if (err instanceof InvalidPipeException) {
    console.error(`Pipe must be a function: ${err.message}`);
  }
}

Prevention

When it happens

Trigger: applyTemplates({ dasherize: true }) or passing a string/number/undefined-result constant under the pipe key, then using '__name@dasherize__' in a path.

Common situations: Passing a boolean flag or option value with the same name as an intended pipe; importing the wrong symbol (a value instead of a function); copying applyTemplates where a helper was refactored to a non-function export.

Related errors


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