angular/angular-cli · warning
Package specifier has no effect when using "migrate-only" op
Error message
Package specifier has no effect when using "migrate-only" option.
What it means
When `ng update --migrate-only` is used, no packages are actually updated — only migrations run — so any package specifier (like a version range) supplied on the command line has no effect. The CLI logs this warning and continues, unless the specifier is the implicit wildcard '*' (no specifier given).
Source
Thrown at packages/angular/cli/src/commands/update/cli.ts:211
for (const request of options.packages ?? []) {
try {
const packageIdentifier = npa(request);
// only registry identifiers are supported
if (!packageIdentifier.registry) {
logger.error(`Package '${request}' is not a registry package identifer.`);
return 1;
}
if (packages.some((v) => v.name === packageIdentifier.name)) {
logger.error(`Duplicate package '${packageIdentifier.name}' specified.`);
return 1;
}
if (options.migrateOnly && packageIdentifier.rawSpec !== '*') {
logger.warn('Package specifier has no effect when using "migrate-only" option.');
}
// Wildcard uses the next tag if next option is used otherwise use latest tag.
// Wildcard is present if no selector is provided on the command line.
if (packageIdentifier.rawSpec === '*') {
packageIdentifier.fetchSpec = options.next ? 'next' : 'latest';
packageIdentifier.type = 'tag';
}
packages.push(packageIdentifier);
} catch (e) {
assertIsError(e);
logger.error(e.message);
return 1;
}
}
View on GitHub (pinned to bb72145f9a)
Solutions
- Remove the package specifier: run `ng update @angular/core --migrate-only` (or just `ng update --migrate-only`) so no meaningless selector is passed.
- If you actually want the package updated too, drop --migrate-only and run a normal `ng update @angular/core@<version>`.
- Update scripts/CI configs to strip version selectors from migrate-only invocations.
Example fix
// before ng update @angular/core@16 --migrate-only // after ng update @angular/core --migrate-only
Defensive patterns
Strategy: validation
Validate before calling
const args = ['ng', 'update', ...pkgs];
if (migrateOnly) {
// strip version selectors when migrate-only
args.splice(args.indexOf('@angular/core@16'), 1, '@angular/core');
} Try / catch
if (migrateOnly && pkgSpecifier !== '*') {
logger.warn('Specifier ignored with --migrate-only; dropping it');
pkgSpecifier = undefined;
} Prevention
- Drop version selectors from `ng update` commands that use --migrate-only.
- Keep separate script targets: one for full updates, one for migrate-only runs.
- Remember --migrate-only never changes package versions.
When it happens
Trigger: Running e.g. `ng update @angular/core@16 --migrate-only` (or any non-'*' rawSpec) so the condition `options.migrateOnly && packageIdentifier.rawSpec !== '*'` is true.
Common situations: Copy-pasting an update command and appending --migrate-only to run only migrations; scripting migrate-only runs while retaining version selectors from previous full-update commands.
Related errors
- An unexpected error happened; could not determine version fo
- An unexpected error happened; package ${name} has no version
- Package ${JSON.stringify(pkgName)} is not in package.json.
- Repository is not clean. Update changes will be mixed with p
- The installed Angular CLI version is outdated. Installing a
AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30).
Data as JSON: /api/errors/f40657a4f4ed0d3c.
Report an issue: GitHub.