{"record":{"id":"ebc4d099202dd738","repo":"angular/angular-cli","slug":"from-requires-that-only-a-single-package-be-pass","errorCode":null,"errorMessage":"--from requires that only a single package be passed.","messagePattern":"--from requires that only a single package be passed\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/angular/cli/src/commands/update/update-resolver.ts","lineNumber":907,"sourceCode":"      try {\n        return isPkgFromRegistry(name, specifier);\n      } catch {\n        logger.warn(`Package ${name} was not found on the registry. Skipping.`);\n\n        return false;\n      }\n    }) as [string, VersionRange][],\n  );\n\n  const packagesOption = options.packages ?? [];\n  const normalizedPackages = packagesOption.reduce((acc, curr) => {\n    return acc.concat(curr.split(','));\n  }, [] as string[]);\n  options.packages = normalizedPackages;\n\n  if (options.migrateOnly && options.from) {\n    if (options.packages.length !== 1) {\n      throw new Error('--from requires that only a single package be passed.');\n    }\n  }\n\n  options.from = _formatVersion(options.from);\n  options.to = _formatVersion(options.to);\n  const usingYarn = options.packageManager === 'yarn';\n\n  const minReleaseAge = await packageManager.getMinimumReleaseAge();\n\n  const getRegistryName = (name: string): string => {\n    const specifier = npmDeps.get(name);\n    if (specifier) {\n      return getRegistryNameAndRange(name, specifier).name;\n    }\n\n    return name;\n  };\n","sourceCodeStart":889,"sourceCodeEnd":925,"githubUrl":"https://github.com/angular/angular-cli/blob/bb72145f9ab45aee29f523236b3a25cd0813a841/packages/angular/cli/src/commands/update/update-resolver.ts#L889-L925","documentation":"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.","triggerScenarios":"`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).","commonSituations":"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.","solutions":["Run one ng update command per package, each with its own --from value.","Omit --from and let the CLI determine versions automatically.","Drop --migrate-only if you intend a full multi-package update rather than a single-package migration."],"exampleFix":"// before\nng update @angular/material @angular/core --migrate-only --from 17\n// after\nng update @angular/material --migrate-only --from 17\nng update @angular/core --migrate-only --from 17","handlingStrategy":"validation","validationCode":"if (options.from && packages.length !== 1) {\n  throw new Error('--from can only be used with a single package');\n}","typeGuard":null,"tryCatchPattern":"try {\n  await ngUpdate(packages, { migrateOnly: true, from });\n} catch (e) {\n  if (e.message.includes('--from requires that only a single package')) {\n    // loop over packages, invoking one ng update per package with its own --from\n  }\n}","preventionTips":["Never combine --migrate-only --from with multiple packages or comma-separated lists.","Script per-package migrations in loops.","Omit --from when the CLI can infer versions from package.json.","Read the ng update option docs before composing flags."],"tags":["angular-cli","cli-arguments","migrate-only","validation"],"backgroundTag":"invalid-cli-flag-combination","analyzedSha":"bb72145f9ab45aee29f523236b3a25cd0813a841","analyzedAt":"2026-08-30T02:47:34.745Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}