{"record":{"id":"e3e26061ecdcf880","repo":"pnpm/pnpm","slug":"config-conflict-frozen-store-with-force","errorCode":"CONFIG_CONFLICT_FROZEN_STORE_WITH_FORCE","errorMessage":"Cannot use force together with frozenStore: --force re-imports packages into the store, which is opened read-only when frozenStore is enabled","messagePattern":"Cannot use force together with frozenStore: --force re-imports packages into the store, which is opened read-only when frozenStore is enabled","errorType":"exception","errorClass":"PnpmError","httpStatus":null,"severity":"error","filePath":"pnpm11/installing/deps-installer/src/install/extendInstallOptions.ts","lineNumber":463,"sourceCode":"  if (extendedOpts.virtualStoreOnly && !extendedOpts.enableModulesDir && !extendedOpts.enableGlobalVirtualStore) {\n    throw new PnpmError('CONFIG_CONFLICT_VIRTUAL_STORE_ONLY_WITH_NO_MODULES_DIR',\n      'Cannot use virtualStoreOnly when enableModulesDir is false (the standard virtual store requires node_modules/.pnpm)')\n  }\n  if (extendedOpts.virtualStoreOnly) {\n    // Ensure .modules.yaml records empty hoist patterns so a subsequent\n    // normal install knows hoisting must be redone from scratch.\n    extendedOpts.hoistPattern = []\n    extendedOpts.publicHoistPattern = []\n  }\n  if (extendedOpts.lockfileOnly) {\n    extendedOpts.ignoreScripts = true\n    if (!extendedOpts.useLockfile) {\n      throw new PnpmError('CONFIG_CONFLICT_LOCKFILE_ONLY_WITH_NO_LOCKFILE',\n        `Cannot generate a ${WANTED_LOCKFILE} because lockfile is set to false`)\n    }\n  }\n  if (extendedOpts.frozenStore && extendedOpts.force) {\n    throw new PnpmError('CONFIG_CONFLICT_FROZEN_STORE_WITH_FORCE',\n      'Cannot use force together with frozenStore: --force re-imports packages into the store, which is opened read-only when frozenStore is enabled')\n  }\n  if (extendedOpts.frozenStore) {\n    // The side-effects cache is written into the store, which frozenStore opens\n    // read-only. Caching is an optimization, not a correctness requirement, so\n    // force it off rather than failing (the writable seed-build already\n    // populated it). Without this, a build under frozenStore (e.g. with the\n    // global virtual store disabled) would attempt a store write.\n    extendedOpts.sideEffectsCacheWrite = false\n  }\n  if (extendedOpts.userAgent.startsWith('npm/')) {\n    extendedOpts.userAgent = `${extendedOpts.packageManager.name}/${extendedOpts.packageManager.version} ${extendedOpts.userAgent}`\n  }\n  extendedOpts.registries = normalizeRegistries(extendedOpts.registries)\n  if (extendedOpts.enableGlobalVirtualStore) {\n    if (extendedOpts.virtualStoreDir == null) {\n      extendedOpts.virtualStoreDir = path.join(extendedOpts.storeDir, 'links')\n    }","sourceCodeStart":445,"sourceCodeEnd":481,"githubUrl":"https://github.com/pnpm/pnpm/blob/5b11d3a15b9022a2109cb18ed96a5d652630371f/pnpm11/installing/deps-installer/src/install/extendInstallOptions.ts#L445-L481","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Drop --force from the invocation","If a re-import is genuinely needed, unset frozenStore for that run","Audit wrapper scripts that append --force to every pnpm call"],"exampleFix":"# before\npnpm install --frozen-store --force   # ERR_PNMP_CONFIG_CONFLICT_FROZEN_STORE_WITH_FORCE\n\n# after\npnpm install --frozen-store","handlingStrategy":"validation","validationCode":"export interface StoreOpts { frozenStore?: boolean, force?: boolean }\n\nexport function storeOptsAreCoherent (opts: StoreOpts): boolean {\n  return !(opts.frozenStore === true && opts.force === true)\n}\n// if (!storeOptsAreCoherent(parsedArgs)) fail fast with guidance","typeGuard":"import util from 'util'\nimport { PnpmError } from '@pnpm/error'\n\nexport const isFrozenStoreForceConflictError = (err: unknown): err is PnpmError =>\n  util.types.isNativeError(err) && (err as PnpmError).code === 'CONFIG_CONFLICT_FROZEN_STORE_WITH_FORCE'","tryCatchPattern":"try {\n  await mutateModules(mutations, opts)\n} catch (err) {\n  if (isFrozenStoreForceConflictError(err)) {\n    const { force: _force, ...rest } = opts\n    return mutateModules(mutations, rest) // retry without force\n  }\n  throw err\n}","preventionTips":["Never blanket-append --force in wrapper scripts; make it an explicit opt-in flag","Keep frozen-store invocations in one dedicated CI/Docker script you can review","Remember frozenStore also disables side-effects cache writes — audit builds that rely on them"],"tags":["config","store","frozen","conflict"],"backgroundTag":null,"analyzedSha":"5b11d3a15b9022a2109cb18ed96a5d652630371f","analyzedAt":"2026-08-16T13:18:59.198Z","schemaVersion":2},"datasetVersion":"2026-08-16T18:17:16.020Z"}