Skip to content

node_modules sometimes purged when running pnpm i --lockfile-only #8654

@Silic0nS0ldier

Description

@Silic0nS0ldier

Verify latest release

  • I verified that the issue exists in the latest pnpm release

pnpm version

No response

Which area(s) of pnpm are affected? (leave empty if unsure)

No response

Link to the code that reproduces this issue or a replay of the bug

No response

Reproduction steps

Unfortunately I've been unable to create a reliable reproduction of the issue. It is influenced by the state of node_modules, the lockfile, pnpm configuration, and seemingly even the user environment.

With luck, my other notes here will shed some light on how this issue could manifest.

Describe the Bug

When running pnpm i --lockfile-only in a workspace, some node_modules directories are being mutated (all packages removed). This is incorrect behaviour, as the docs state that for --lockfile-only "Nothing gets written to the node_modules directory.".

Before this is done, the following question is posed (sometimes many, sometimes one, sometimes it doesn't show up at all).

The modules directories will be removed and reinstalled from scratch. Proceed? (Y/n)

Once any answer is given, the following message is shown and node_modules is purged.

Recreating /___/node_modules

The underlying issue here appears to be that safeguards intended for actual installs aren't gated behind !opts.lockfileOnly.


Potentially useful source references;

  • async function validateModules (

    Determines if purge is necessary and purges. Behind the scenes this decision is made based on the following caught error.
    modules directory (at "/__repo_root__") was installed with optionalDependencies, dependencies. Current install wants optionalDependencies, dependencies, devDependencies.
  • if (purged) {
    await purgeModulesDirsOfImporters(opts, importersToPurge)
    }

    The specific call used to initiate modules purge.
  • const confirmed = await enquirer.prompt({
    type: 'confirm',
    name: 'question',
    message: importers.length === 1
    ? `The modules directory at "${importers[0].modulesDir}" will be removed and reinstalled from scratch. Proceed?`
    : 'The modules directories will be removed and reinstalled from scratch. Proceed?',
    initial: true,
    })

    Confirmation is bugged. enquirer returns { question: true|false }, so currently the purge will always be performed (unless skipped via --config.confirmModulesPurge=false).
  • const { purged } = await validateModules(importersContext.modules, importersContext.projects, {

    Purge is triggered by function getContext. Going purely off the name, it seems like this function should not have side effects.

Expected Behavior

--lockfile-only leaves node_modules untouched, no matter what it contains (namely, content from another package manager).

Which Node.js version are you using?

20.18.0

Which operating systems have you used?

  • macOS
  • Windows
  • Linux

If your OS is a Linux based, which one it is? (Include the version if relevant)

Ubuntu

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions