angular/angular-cli · warning

PackageGroup metadata for ${packageJson.name} is malformed.

Error message

PackageGroup metadata for ${packageJson.name} is malformed. Ignoring.

What it means

During update resolution, the CLI reads a package's 'ng-update' PackageGroup metadata (which maps sibling packages to versions that must migrate together). If that metadata exists but is structurally malformed (not a plain object of member→version), it is logged as malformed, ignored, and resolution proceeds without the group constraints.

Source

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

          group[name] = packageJson.version;

          return group;
        },
        {} as { [key: string]: string },
      );
    } else if (typeof packageGroup == 'object' && packageGroup !== null) {
      result.packageGroup = Object.entries(packageGroup).reduce(
        (group, [name, version]) => {
          if (typeof version == 'string') {
            group[name] = version;
          }

          return group;
        },
        {} as { [key: string]: string },
      );
    } else {
      logger.warn(`PackageGroup metadata for ${packageJson.name} is malformed. Ignoring.`);
    }
  }

  if (typeof metadata['packageGroupName'] == 'string') {
    result.packageGroupName = metadata['packageGroupName'];
  }

  if (typeof metadata['migrations'] == 'string') {
    result.migrations = metadata['migrations'];
  }

  return result;
}

export function isPnpActive(workspaceRoot: string): boolean {
  return (
    process.versions.pnp !== undefined ||
    existsSync(path.join(workspaceRoot, '.pnp.cjs')) ||

View on GitHub (pinned to bb72145f9a)

Solutions

  1. Identify the offending package (named in the warning) and check its package.json 'ng-update' field; report/fix it upstream if it's a third-party lib.
  2. Pin to a stable published version of the package whose metadata is valid instead of next/canary.
  3. Proceed without action if the group is unimportant: the CLI ignores it and continues the update.
  4. If it's your own library, correct the packageGroup to a flat object of package name → version range and republish.

Example fix

// before: malformed ng-update metadata
"ng-update": { "packageGroup": ["@angular/cdk"] }
// after: valid group map
"ng-update": { "packageGroup": { "@angular/cdk": "0.0.0-PLACEHOLDER" } }
Defensive patterns

Strategy: fallback

Validate before calling

const ngUpdate = pkg['ng-update'] ?? {};
const group = ngUpdate.packageGroup;
const valid = group && typeof group === 'object' && !Array.isArray(group)
  && Object.values(group).every(v => typeof v === 'string');
if (!valid) console.warn(`${pkg.name} packageGroup malformed; group constraints will be ignored`);

Type guard

function isPackageGroup(v: unknown): v is Record<string, string> {
  return !!v && typeof v === 'object' && !Array.isArray(v)
    && Object.entries(v).every(([k, val]) => typeof k === 'string' && typeof val === 'string');
}

Try / catch

try {
  applyPackageGroup(metadata);
} catch {
  logger.warn('PackageGroup malformed; updating without group constraints');
}

Prevention

When it happens

Trigger: _getUpdateMetadata parses the 'packageGroup'/'packageGroupRange' style metadata of a package being updated (e.g., @angular/core) and the normalized result is not a valid Record<string, string>, taking the else branch that warns.

Common situations: A library published a broken ng-update packageGroup (wrong types, nested objects, arrays); using canary/next builds of Angular packages where metadata is temporarily inconsistent; a registry mirror serving altered package.json.

Understand the failure class

Related errors


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