angular/angular-cli · error · Error

--from requires that only a single package be passed.

Error message

--from requires that only a single package be passed.

What it means

Thrown when `ng update --migrate-only --from <version>` is invoked with more than one package. The --from option specifies a single starting version for migration, which is only meaningful for exactly one package, so the CLI validates the package count and fails fast.

Solutions

  1. Run one ng update command per package, each with its own --from value.
  2. Omit --from and let the CLI determine versions automatically.
  3. Drop --migrate-only if you intend a full multi-package update rather than a single-package migration.

Example fix

// before
ng update @angular/material @angular/core --migrate-only --from 17
// after
ng update @angular/material --migrate-only --from 17
ng update @angular/core --migrate-only --from 17
Defensive patterns

Strategy: validation

Validate before calling

if (options.from && packages.length !== 1) {
  throw new Error('--from can only be used with a single package');
}

Try / catch

try {
  await ngUpdate(packages, { migrateOnly: true, from });
} catch (e) {
  if (e.message.includes('--from requires that only a single package')) {
    // loop over packages, invoking one ng update per package with its own --from
  }
}

Prevention

When it happens

Trigger: `ng update pkg-a pkg-b --migrate-only --from 1.2.3`; comma-separated names like `ng update pkg-a,pkg-b --migrate-only --from x` (commas are normalized into separate packages before the check).

Common situations: Scripting bulk migrations and passing multiple packages with a shared --from; copy-pasting a multi-package update command and adding --migrate-only --from; misunderstanding that --from applies per package.

Related errors


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

Appendix: source

Thrown at packages/angular/cli/src/commands/update/update-resolver.ts:907

      try {
        return isPkgFromRegistry(name, specifier);
      } catch {
        logger.warn(`Package ${name} was not found on the registry. Skipping.`);

        return false;
      }
    }) as [string, VersionRange][],
  );

  const packagesOption = options.packages ?? [];
  const normalizedPackages = packagesOption.reduce((acc, curr) => {
    return acc.concat(curr.split(','));
  }, [] as string[]);
  options.packages = normalizedPackages;

  if (options.migrateOnly && options.from) {
    if (options.packages.length !== 1) {
      throw new Error('--from requires that only a single package be passed.');
    }
  }

  options.from = _formatVersion(options.from);
  options.to = _formatVersion(options.to);
  const usingYarn = options.packageManager === 'yarn';

  const minReleaseAge = await packageManager.getMinimumReleaseAge();

  const getRegistryName = (name: string): string => {
    const specifier = npmDeps.get(name);
    if (specifier) {
      return getRegistryNameAndRange(name, specifier).name;
    }

    return name;
  };

View on GitHub (pinned to bb72145f9a)