pnpm/pnpm · error · PnpmError

CONFIG_CONFLICT_LOCKFILE_ONLY_WITH_NO_LOCKFILE

CONFIG_CONFLICT_LOCKFILE_ONLY_WITH_NO_LOCKFILE

Error message

Cannot generate a ${WANTED_LOCKFILE} because lockfile is set to false

What it means

lockfileOnly (--lockfile-only) tells pnpm to resolve and write pnpm-lock.yaml and skip linking; `lockfile: false` (useLockfile off) tells pnpm to not use any lockfile at all. Asking for a lockfile-only run while lockfiles are disabled is contradictory, so option extension fails fast. Note the adjacent code: lockfileOnly also forces ignoreScripts on.

Source

Thrown at pnpm11/installing/deps-installer/src/install/extendInstallOptions.ts:458

    convergeDeclaredRanges: extendedOpts.convergeDeclaredRanges,
    lockfileDir: extendedOpts.lockfileDir,
    packageExtensions: extendedOpts.packageExtensions,
    ignoredOptionalDependencies: extendedOpts.ignoredOptionalDependencies,
  })
  if (extendedOpts.virtualStoreOnly && !extendedOpts.enableModulesDir && !extendedOpts.enableGlobalVirtualStore) {
    throw new PnpmError('CONFIG_CONFLICT_VIRTUAL_STORE_ONLY_WITH_NO_MODULES_DIR',
      'Cannot use virtualStoreOnly when enableModulesDir is false (the standard virtual store requires node_modules/.pnpm)')
  }
  if (extendedOpts.virtualStoreOnly) {
    // Ensure .modules.yaml records empty hoist patterns so a subsequent
    // normal install knows hoisting must be redone from scratch.
    extendedOpts.hoistPattern = []
    extendedOpts.publicHoistPattern = []
  }
  if (extendedOpts.lockfileOnly) {
    extendedOpts.ignoreScripts = true
    if (!extendedOpts.useLockfile) {
      throw new PnpmError('CONFIG_CONFLICT_LOCKFILE_ONLY_WITH_NO_LOCKFILE',
        `Cannot generate a ${WANTED_LOCKFILE} because lockfile is set to false`)
    }
  }
  if (extendedOpts.frozenStore && extendedOpts.force) {
    throw new PnpmError('CONFIG_CONFLICT_FROZEN_STORE_WITH_FORCE',
      'Cannot use force together with frozenStore: --force re-imports packages into the store, which is opened read-only when frozenStore is enabled')
  }
  if (extendedOpts.frozenStore) {
    // The side-effects cache is written into the store, which frozenStore opens
    // read-only. Caching is an optimization, not a correctness requirement, so
    // force it off rather than failing (the writable seed-build already
    // populated it). Without this, a build under frozenStore (e.g. with the
    // global virtual store disabled) would attempt a store write.
    extendedOpts.sideEffectsCacheWrite = false
  }
  if (extendedOpts.userAgent.startsWith('npm/')) {
    extendedOpts.userAgent = `${extendedOpts.packageManager.name}/${extendedOpts.packageManager.version} ${extendedOpts.userAgent}`
  }

View on GitHub (pinned to 5b11d3a15b)

Solutions

  1. Remove `lockfile=false` (or pass --lockfile) so the lockfile-only run can write pnpm-lock.yaml
  2. If lockfiles must stay off, remove the --lockfile-only step from the pipeline

Example fix

# before (.npmrc)
lockfile=false
# pnpm install --lockfile-only fails with CONFIG_CONFLICT_LOCKFILE_ONLY_WITH_NO_LOCKFILE

# after: delete the line, keep the job
# lockfile=false
pnpm install --lockfile-only
Defensive patterns

Strategy: validation

Validate before calling

export interface LockfileOpts { lockfileOnly?: boolean, useLockfile?: boolean }

export function lockfileOptsAreCoherent (opts: LockfileOpts): boolean {
  return !(opts.lockfileOnly === true && opts.useLockfile === false)
}
// if (!lockfileOptsAreCoherent(parsedConfig)) fail fast with guidance

Type guard

import util from 'util'
import { PnpmError } from '@pnpm/error'

export const isLockfileOnlyConflictError = (err: unknown): err is PnpmError =>
  util.types.isNativeError(err) && (err as PnpmError).code === 'CONFIG_CONFLICT_LOCKFILE_ONLY_WITH_NO_LOCKFILE'

Try / catch

try {
  await mutateModules(mutations, opts)
} catch (err) {
  if (isLockfileOnlyConflictError(err)) {
    throw new Error('remove lockfile=false or drop --lockfile-only', { cause: err })
  }
  throw err
}

Prevention

When it happens

Trigger: Install with lockfileOnly true and useLockfile false — for example `pnpm install --lockfile-only` while .npmrc or pnpm-workspace.yaml contains lockfile=false.

Common situations: A leftover `lockfile=false` from earlier experiments; a workspace where lockfiles are disabled but a CI job tries to regenerate one with --lockfile-only.

Related errors


AI-assisted analysis of pnpm/pnpm@5b11d3a15b (2026-08-16). Data as JSON: /api/errors/999b2331eb5d5c14. Report an issue: GitHub.