{"record":{"id":"57df53e9829d32f5","repo":"angular/angular-cli","slug":"unregistered-task-name-addendum","errorCode":null,"errorMessage":"Unregistered task \"${name}\"${addendum}.","messagePattern":"Unregistered task \"(.+?)\"(.+?)\\.","errorType":"exception","errorClass":"UnregisteredTaskException","httpStatus":null,"severity":"error","filePath":"packages/angular_devkit/schematics/src/engine/engine.ts","lineNumber":287,"sourceCode":"    };\n\n    const maybeNewContext = this._host.transformContext(context);\n    if (maybeNewContext) {\n      context = maybeNewContext;\n    }\n\n    const taskScheduler = new TaskScheduler(context);\n    const host = this._host;\n    this._taskSchedulers.push(taskScheduler);\n\n    function addTask<T extends object>(\n      task: TaskConfigurationGenerator<T>,\n      dependencies?: Array<TaskId>,\n    ): TaskId {\n      const config = task.toConfiguration();\n\n      if (!host.hasTaskExecutor(config.name)) {\n        throw new UnregisteredTaskException(config.name, schematic.description);\n      }\n\n      config.dependencies = config.dependencies || [];\n      if (dependencies) {\n        config.dependencies.unshift(...dependencies);\n      }\n\n      return taskScheduler.schedule(config);\n    }\n\n    return context;\n  }\n\n  createSchematic(\n    name: string,\n    collection: Collection<CollectionT, SchematicT>,\n    allowPrivate = false,\n  ): Schematic<CollectionT, SchematicT> {","sourceCodeStart":269,"sourceCodeEnd":305,"githubUrl":"https://github.com/angular/angular-cli/blob/bb72145f9ab45aee29f523236b3a25cd0813a841/packages/angular_devkit/schematics/src/engine/engine.ts#L269-L305","documentation":"When a schematic schedules a post-execution task via context.addTask(...), the engine verifies that a task executor was registered for the task's name (host.hasTaskExecutor). If no executor with that name is registered on the engine host, the task could never actually run, so UnregisteredTaskException is thrown naming the missing executor and the schematic that requested it. This keeps schematics from silently scheduling no-op work.","triggerScenarios":"Calling context.addTask(new SomeTaskGenerator(...), deps) inside a schematic rule where addTask's task.toConfiguration().name has no matching executor registered via host.registerTaskExecutor (e.g. addTask(new NodePackageInstallTask()) while the engine host was created without the NodePackageInstallTaskExecutor).","commonSituations":"Custom test harnesses or programmatic engine setups that omit standard executors (package install, RepositoryInitializer/initial-git-commit, TslintFix, RunSchematic) that the Angular CLI registers by default; renaming a task in a custom executor without updating the schematic that schedules it; version drift where a schematic schedules a task whose executor moved to another package.","solutions":["Register the missing executor on the engine host before running schematics, e.g. host.registerTaskExecutor(NodePackageInstallTaskExecutor) (or the executor matching the task name in the message).","Check the task name in the error against your schematic's addTask call — fix a typo or outdated task class import.","If using Angular CLI tooling, build your host with the standard executors rather than a bare HostTree-based engine host.","As a last resort in test code, stub/replace the task generator so no unregistered task is scheduled."],"exampleFix":"// before\nconst engine = new SchematicEngine(new HostTreeEngineHost(hostTree));\n// schematic: return context.addTask(new NodePackageInstallTask()); // throws: Unregistered task \"node-package\"\n\n// after\nimport { NodePackageInstallTaskExecutor } from '@angular-devkit/schematics/tasks/node-package/executor';\nhost.registerTaskExecutor(NodePackageInstallTaskExecutor);\nconst engine = new SchematicEngine(new HostTreeEngineHost(hostTree));","handlingStrategy":"validation","validationCode":"function assertTaskExecutorRegistered(host: SchematicEngineHost, generator: { toConfiguration(): { name: string } }): void {\n  const taskName = generator.toConfiguration().name;\n  if (!host.hasTaskExecutor(taskName)) {\n    throw new Error(`Register executor for task \"${taskName}\" before running schematics.`);\n  }\n}","typeGuard":null,"tryCatchPattern":"import { UnregisteredTaskException } from '@angular-devkit/schematics';\ntry {\n  return context.addTask(new NodePackageInstallTask());\n} catch (e) {\n  if (e instanceof UnregisteredTaskException) {\n    // register the executor named in e.message on the engine host\n  } else { throw e; }\n}","preventionTips":["Always register the standard executors (NodePackageInstallTaskExecutor, RepositoryInitializerTaskExecutor, etc.) on custom engine hosts.","Keep the task class and its executor imported from the same package version.","Add an integration test that runs every schematic end-to-end so unregistered tasks fail in CI, not in users' builds."],"tags":["schematics","tasks","registration","configuration"],"backgroundTag":"unregistered-task-executor","analyzedSha":"bb72145f9ab45aee29f523236b3a25cd0813a841","analyzedAt":"2026-08-30T02:47:34.745Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}