{"record":{"id":"4aebf946a1edfa3a","repo":"angular/angular-cli","slug":"pipe-pipe-is-invalid","errorCode":null,"errorMessage":"Pipe \"${pipe}\" is invalid.","messagePattern":"Pipe \"(.+?)\" is invalid\\.","errorType":"exception","errorClass":"InvalidPipeException","httpStatus":null,"severity":"error","filePath":"packages/angular_devkit/schematics/src/rules/template.ts","lineNumber":138,"sourceCode":"\n        if (typeof replacement == 'function') {\n          replacement = replacement.call(data, original);\n        }\n\n        if (replacement === undefined) {\n          throw new OptionIsNotDefinedException(name);\n        }\n\n        replacement = pipes.reduce((acc: string, pipe: string) => {\n          if (!pipe) {\n            return acc;\n          }\n          if (!(pipe in data)) {\n            throw new UnknownPipeException(pipe);\n          }\n          const pipeFn = data[pipe];\n          if (typeof pipeFn != 'function') {\n            throw new InvalidPipeException(pipe);\n          }\n\n          // Coerce to string.\n          return '' + pipeFn(acc);\n        }, '' + replacement);\n      }\n\n      path = path.substring(0, start) + replacement + path.substring(end + ieL);\n\n      start = path.indexOf(options.interpolationStart);\n      // See above.\n      end = path.indexOf(options.interpolationEnd, start + isL + 1);\n    }\n\n    return { path: normalize(path), content };\n  };\n}\n","sourceCodeStart":120,"sourceCodeEnd":156,"githubUrl":"https://github.com/angular/angular-cli/blob/bb72145f9ab45aee29f523236b3a25cd0813a841/packages/angular_devkit/schematics/src/rules/template.ts#L120-L156","documentation":"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'.","triggerScenarios":"applyTemplates({ dasherize: true }) or passing a string/number/undefined-result constant under the pipe key, then using '__name@dasherize__' in a path.","commonSituations":"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.","solutions":["Ensure the value bound to the pipe key is a function: (acc: string) => string.","Rename conflicting keys so options data and pipe functions don't collide.","Check the import — import the helper function, not a constant, e.g. `import { strings } from '@angular-devkit/core'` then strings.dasherize."],"exampleFix":"// before\napplyTemplates({ dasherize: options.dasherize }) // boolean\n// after\napplyTemplates({ dasherize: (s: string) => strings.dasherize(s) })","handlingStrategy":"validation","validationCode":"if (typeof data[pipe] !== 'function') {\n  throw new Error(`Template pipe \"${pipe}\" must be a (string) => string function`);\n}","typeGuard":"function isPipeFunction(v: unknown): v is (acc: string) => string {\n  return typeof v === 'function';\n}","tryCatchPattern":"try {\n  return mergeWith(apply(source, [template(options)]));\n} catch (err) {\n  if (err instanceof InvalidPipeException) {\n    console.error(`Pipe must be a function: ${err.message}`);\n  }\n}","preventionTips":["Never bind plain values/flags under names used as pipes in templates.","Type your template options object with pipe keys as functions.","When refactoring helpers, verify exports are still functions."],"tags":["schematics","template","pipes","type-mismatch"],"backgroundTag":"invalid-template-pipe","analyzedSha":"bb72145f9ab45aee29f523236b3a25cd0813a841","analyzedAt":"2026-08-30T02:47:34.745Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}