angular/angular-cli · error · CommandModuleError

A single package must be specified when using the 'migrate-o

Error message

A single package must be specified when using the 'migrate-only' option.

What it means

When --migrate-only is used, the update command requires exactly one package name, because migration runs the specified package's migration scripts only. Passing zero or multiple packages is ambiguous and rejected with a CommandModuleError.

Source

Thrown at packages/angular/cli/src/commands/update/cli.ts:154

      .check(({ packages, 'allow-dirty': allowDirty, 'migrate-only': migrateOnly }) => {
        const { logger } = this.context;

        // This allows the user to easily reset any changes from the update.
        if (packages?.length && !checkCleanGit(this.context.root)) {
          if (allowDirty) {
            logger.warn(
              'Repository is not clean. Update changes will be mixed with pre-existing changes.',
            );
          } else {
            throw new CommandModuleError(
              'Repository is not clean. Please commit or stash any changes before updating.',
            );
          }
        }

        if (migrateOnly) {
          if (packages?.length !== 1) {
            throw new CommandModuleError(
              `A single package must be specified when using the 'migrate-only' option.`,
            );
          }
        }

        return true;
      })
      .strict();
  }

  async run(options: Options<UpdateCommandArgs>): Promise<number | void> {
    const { logger, packageManager } = this.context;

    // Check if the current installed CLI version is older than the latest compatible version.
    // Skip when running `ng update` without a package name as this will not trigger an actual update.
    if (!disableVersionCheck && options.packages?.length) {
      const cliVersionToInstall = await checkCLIVersion(
        options.packages,

View on GitHub (pinned to bb72145f9a)

Solutions

  1. Specify exactly one package: `ng update @angular/core --migrate-only` (optionally with --from/--to).
  2. If you intended a full update of several packages, drop --migrate-only.
  3. Run one `ng update <pkg> --migrate-only` per package that has migrations.

Example fix

// before
ng update --migrate-only
// after
ng update @angular/material --migrate-only --from 15 --to 16
Defensive patterns

Strategy: validation

Validate before calling

if (migrateOnly && packages.length !== 1) {
  throw new Error(`--migrate-only requires exactly one package, got: ${packages.length}`);
}

Type guard

function isSinglePackage(args: { packages?: string[]; migrateOnly?: boolean }): boolean {
  return !args.migrateOnly || args.packages?.length === 1;
}

Prevention

When it happens

Trigger: `ng update --migrate-only` with no package; `ng update pkg1 pkg2 --migrate-only` with multiple packages; combining --migrate-only with --all semantics.

Common situations: Copy-pasting multi-package update commands and appending --migrate-only; forgetting the package name when running only migrations.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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