angular/angular-cli · warning

Package dependency "${name}" already exists with a different

Error message

Package dependency "${name}" already exists with a different specifier. "${existingSpecifier}" will be replaced with "${specifier}".

What it means

addDependency (packages/schematics/angular/utility/dependency.ts) inserts a package into package.json. When the package already exists with a different version specifier, the default behavior (ExistingBehavior.Replace) warns that the existing specifier is being overwritten with the new one.

Source

Thrown at packages/schematics/angular/utility/dependency.ts:201

      // Section is not present. The dependency can be added to a new object literal for the section.
      manifest[type] = { [name]: specifier };
    } else {
      const existingSpecifier = dependencySection[name];

      if (existingSpecifier === specifier) {
        // Already present with same specifier
        return;
      }

      if (existingSpecifier) {
        // Already present but different specifier

        if (existing === ExistingBehavior.Skip) {
          return;
        }

        // ExistingBehavior.Replace is the only other behavior currently
        context.logger.warn(
          `Package dependency "${name}" already exists with a different specifier. ` +
            `"${existingSpecifier}" will be replaced with "${specifier}".`,
        );
      }

      // Add new dependency in alphabetical order
      const entries = Object.entries(dependencySection);
      entries.push([name, specifier]);
      entries.sort((a, b) => a[0].localeCompare(b[0]));
      manifest[type] = Object.fromEntries(entries);
    }

    tree.overwrite(packageJsonPath, JSON.stringify(manifest, null, 2));

    const installPaths = installTasks.get(context) ?? new Set<string>();
    if (
      install === InstallBehavior.Always ||
      (install === InstallBehavior.Auto && !installPaths.has(packageJsonPath))

View on GitHub (pinned to bb72145f9a)

Solutions

  1. Accept the replacement if the schematic's version is what you want; commit the updated package.json
  2. If you need to keep your specifier, pin it back after the schematic runs or pre-update the dependency to a compatible range before running
  3. Review the package.json diff after ng update/ng add to confirm no unexpected version changes

Example fix

// before (package.json)
"@angular/core": "~16.2.0"
// after schematic run (warned replacement)
"@angular/core": "^17.0.0"
Defensive patterns

Strategy: validation

Validate before calling

// before running schematics that add deps, diff installed versions against expected
const pkg = require('./package.json');
const name = '@angular/core';
const expectedRange = '^17.0.0';
if (pkg.dependencies?.[name] && pkg.dependencies[name] !== expectedRange) {
  console.warn(`${name} will be replaced: ${pkg.dependencies[name]} -> ${expectedRange}`);
}

Type guard

function dependencyWillChange(pkgJson, name, specifier) {
  const current = pkgJson?.dependencies?.[name] ?? pkgJson?.devDependencies?.[name];
  return typeof current === 'string' && current !== specifier;
}

Prevention

When it happens

Trigger: Any schematic calling addDependency (directly or via addDependenciesToPackageJson) where package.json already lists the package under a different range, e.g. "~16.2.0" present while the schematic installs "^17.0.0".

Common situations: ng update / ng add flows where the workspace has a manually pinned or locally patched version of a dependency (e.g. @angular/core, zone.js, typescript) that differs from the schematic's target version.

Related errors


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