pnpm/pnpm · error · PnpmError

CONFIG_CONFLICT_FROZEN_STORE_WITH_FORCE

CONFIG_CONFLICT_FROZEN_STORE_WITH_FORCE

Error message

Cannot use force together with frozenStore: --force re-imports packages into the store, which is opened read-only when frozenStore is enabled

What it means

frozenStore opens the content-addressable store read-only (reproducible/offline builds); --force re-imports packages into the store. The two are mutually exclusive, so pnpm rejects the combination during option extension. The adjacent logic shows the related softer rule: under frozenStore the side-effects cache write is silently disabled rather than failing.

Source

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

  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}`
  }
  extendedOpts.registries = normalizeRegistries(extendedOpts.registries)
  if (extendedOpts.enableGlobalVirtualStore) {
    if (extendedOpts.virtualStoreDir == null) {
      extendedOpts.virtualStoreDir = path.join(extendedOpts.storeDir, 'links')
    }

View on GitHub (pinned to 5b11d3a15b)

Solutions

  1. Drop --force from the invocation
  2. If a re-import is genuinely needed, unset frozenStore for that run
  3. Audit wrapper scripts that append --force to every pnpm call

Example fix

# before
pnpm install --frozen-store --force   # ERR_PNMP_CONFIG_CONFLICT_FROZEN_STORE_WITH_FORCE

# after
pnpm install --frozen-store
Defensive patterns

Strategy: validation

Validate before calling

export interface StoreOpts { frozenStore?: boolean, force?: boolean }

export function storeOptsAreCoherent (opts: StoreOpts): boolean {
  return !(opts.frozenStore === true && opts.force === true)
}
// if (!storeOptsAreCoherent(parsedArgs)) fail fast with guidance

Type guard

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

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

Try / catch

try {
  await mutateModules(mutations, opts)
} catch (err) {
  if (isFrozenStoreForceConflictError(err)) {
    const { force: _force, ...rest } = opts
    return mutateModules(mutations, rest) // retry without force
  }
  throw err
}

Prevention

When it happens

Trigger: Install with frozenStore true and force true at the same time — for example a Docker build that sets --frozen-store while a wrapper script unconditionally appends --force.

Common situations: CI/Docker recipes that stack flags blindly; converting a build to frozen store without cleaning up an existing --force in a Makefile or entrypoint script.

Related errors


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