Skip to content

nx migrate ignores registries.default from pnpm-workspace.yaml #35843

@minijus

Description

@minijus

Current Behavior

nx migrate latest (and nx migrate <version>) ignores the registries.default setting from pnpm-workspace.yaml and falls back to https://registry.npmjs.org. This affects two phases of the migration:

  1. Temp directory install phasenxCliPath() calls copyPackageManagerConfigurationFiles() which copies .npmrc but not pnpm-workspace.yaml to the temp directory. Since pnpm v11, registry config belongs in pnpm-workspace.yaml via registries.default. Without that file in the temp dir, pnpm falls back to npmjs.org.

  2. Version resolution phasepackageRegistryView() runs pnpm view nx@latest version without passing cwd: workspaceRoot to execAsync. While the child process typically inherits the parent's cwd, this is fragile and doesn't guarantee pnpm-workspace.yaml is discoverable.

$ NX_SKIP_PROVENANCE_CHECK=true pnpm nx migrate 22.7.5 --verbose
[WARN] GET https://registry.npmjs.org/nx error (UNABLE_TO_GET_ISSUER_CERT_LOCALLY). Will retry in 10 seconds. 2 retries left.

Even when registry= is added to .npmrc as a workaround (which fixes phase 1), phase 2 still fails:

NX   Unable to resolve version nx@latest.

Error: Unable to resolve version nx@latest.
    at resolvePackageVersionUsingRegistry (/.../nx/dist/src/utils/package-manager.js:428:15)
    at async parseTargetPackageAndVersion (/.../nx/dist/src/command-line/migrate/migrate.js:539:35)

Expected Behavior

nx migrate should respect registries.default from pnpm-workspace.yaml — the canonical location for registry configuration in pnpm v11+. Users who configure their registry exclusively via pnpm-workspace.yaml (without duplicating in .npmrc) should be able to run migrations successfully.

GitHub Repo

Any pnpm v11 workspace with registries.default in pnpm-workspace.yaml and no registry= in .npmrc.

Steps to Reproduce

  1. Create a workspace with pnpm v11 and pnpm-workspace.yaml:

    registries:
      default: https://your-private-registry.example.com/npm/
  2. Ensure there is no registry= line in .npmrc (or no .npmrc at all).

  3. Run:

    pnpm nx migrate latest
  4. Observe: pnpm attempts to fetch from https://registry.npmjs.org instead of the configured private registry.

Nx Report

Nx: 22.7.5
pnpm: 11.5.0
OS: macOS (arm64)

Failure Logs

$ NX_SKIP_PROVENANCE_CHECK=true pnpm nx migrate latest --verbose
[WARN] GET https://registry.npmjs.org/nx error (UNABLE_TO_GET_ISSUER_CERT_LOCALLY). Will retry in 10 seconds. 2 retries left.
[WARN] GET https://registry.npmjs.org/nx error (UNABLE_TO_GET_ISSUER_CERT_LOCALLY). Will retry in 1 minute. 1 retries left.

# After adding registry= to .npmrc as workaround:
$ NX_SKIP_PROVENANCE_CHECK=true pnpm nx migrate latest --verbose
Packages: +112
Done in 5s using pnpm v11.5.0

 NX   Unable to resolve version nx@latest.

Error: Unable to resolve version nx@latest.
    at resolvePackageVersionUsingRegistry (/private/var/folders/.../T/tmp-29072-.../node_modules/.pnpm/nx@22.7.5/node_modules/nx/dist/src/utils/package-manager.js:428:15)
    at async parseTargetPackageAndVersion (/private/var/folders/.../nx/dist/src/command-line/migrate/migrate.js:539:35)

Package Manager Version

pnpm 11.5.0

Operating System

  • macOS
  • Linux
  • Windows
  • Other (Please specify)

Additional Information

The issue is in packages/nx/src/utils/package-manager.ts:

  1. copyPackageManagerConfigurationFiles (line ~403) only copies .npmrc, .yarnrc, .yarnrc.yml, and bunfig.toml. It does not copy pnpm-workspace.yaml, which since pnpm v11 is the canonical source of registry configuration (registries.default).

  2. packageRegistryView (line ~582) runs pnpm view without passing cwd:

    const { stdout } = await execAsync(`${pm} view ${pkg}@${version} ${args}`, {
      windowsHide: true,
    });

    It should pass { cwd: workspaceRoot, windowsHide: true } to ensure pnpm can discover the workspace config.

Suggested fix

One or more of:

  • Pass cwd: workspaceRoot to the execAsync call in packageRegistryView
  • Read registries.default from pnpm-workspace.yaml and pass it via npm_config_registry env variable to the spawned commands
  • Copy a minimal pnpm-workspace.yaml (containing only registries:) to the temp directory in copyPackageManagerConfigurationFiles

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions