angular/angular-cli · error · SchematicsException

Option "implements" is required.

Error message

Option "implements" is required.

What it means

The `guard` schematic requires the `implements` option to know which guard interface(s) to generate (CanActivate, CanMatch, etc.). If `options.implements` is missing or empty, the generator cannot determine the guard's type or template, so it throws this SchematicsException immediately. The Angular CLI normally supplies this via the `--implements` flag (with a schema default), so this mainly fires on direct/programmatic schematic invocation.

Source

Thrown at packages/schematics/angular/guard/index.ts:17

/**
 * @license
 * Copyright Google LLC All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.dev/license
 */

import { Rule, SchematicsException } from '@angular-devkit/schematics';

import { generateFromFiles } from '../utility/generate-from-files';

import { Implement as GuardInterface, Schema as GuardOptions } from './schema';

export default function (options: GuardOptions): Rule {
  if (!options.implements) {
    throw new SchematicsException('Option "implements" is required.');
  }
  if (options.implements.length > 1 && options.functional) {
    throw new SchematicsException(
      'Can only specify one value for implements when generating a functional guard.',
    );
  }

  if (options.functional) {
    const guardType = options.implements[0] + 'Fn';

    return generateFromFiles({ ...options, templateFilesDirectory: './type-files' }, { guardType });
  } else {
    const implementations = options.implements
      .map((implement) => (implement === 'CanDeactivate' ? 'CanDeactivate<unknown>' : implement))
      .join(', ');
    const commonRouterNameImports = ['ActivatedRouteSnapshot', 'RouterStateSnapshot'];
    const routerNamedImports: string[] = [...options.implements, 'MaybeAsync', 'GuardResult'];

View on GitHub (pinned to bb72145f9a)

Solutions

  1. Pass the flag on the CLI: `ng generate guard <name> --implements CanActivate` (or `CanMatch`, `CanActivateChild`, `CanDeactivate`, `CanLoad`, `CanActivateFn`-style functional names depending on version).
  2. When calling the schematic programmatically, include `implements` in the options object passed to `execute`/`schedule`.
  3. For functional guards, provide exactly one interface value, e.g. `--implements CanActivate --functional`.

Example fix

// before
schematicRunner.runSchematic('guard', { name: 'auth' });
// after
schematicRunner.runSchematic('guard', { name: 'auth', implements: ['CanActivate'] });
Defensive patterns

Strategy: validation

Validate before calling

const opts = { name: 'auth', implements: ['CanActivate'] };
if (!Array.isArray(opts.implements) || opts.implements.length === 0) {
  throw new Error('Option "implements" is required, e.g. --implements CanActivate');
}

Type guard

function hasImplements(o: { implements?: string[] }): o is { implements: string[] } {
  return Array.isArray(o.implements) && o.implements.length > 0;
}

Try / catch

try {
  await runSchematic('guard', options);
} catch (e) {
  if (e instanceof SchematicsException && e.message.includes('Option "implements" is required')) {
    console.error('Pass --implements <Interface> when generating a guard.');
  } else throw e;
}

Prevention

When it happens

Trigger: Invoking the guard schematic programmatically (e.g. via the Schematics API or a custom tool) without `implements` in the options object, or with `implements: []`, bypassing the CLI's schema validation.

Common situations: Custom internal tooling wrapping `@schematics/angular` guard generation; schematic collections extending the guard schematic and forgetting to pass `implements` through; older scripts written before schema defaults changed.

Related errors


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