{"record":{"id":"999b2331eb5d5c14","repo":"pnpm/pnpm","slug":"config-conflict-lockfile-only-with-no-lockfile","errorCode":"CONFIG_CONFLICT_LOCKFILE_ONLY_WITH_NO_LOCKFILE","errorMessage":"Cannot generate a ${WANTED_LOCKFILE} because lockfile is set to false","messagePattern":"Cannot generate a (.+?) because lockfile is set to false","errorType":"exception","errorClass":"PnpmError","httpStatus":null,"severity":"error","filePath":"pnpm11/installing/deps-installer/src/install/extendInstallOptions.ts","lineNumber":458,"sourceCode":"    convergeDeclaredRanges: extendedOpts.convergeDeclaredRanges,\n    lockfileDir: extendedOpts.lockfileDir,\n    packageExtensions: extendedOpts.packageExtensions,\n    ignoredOptionalDependencies: extendedOpts.ignoredOptionalDependencies,\n  })\n  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  }","sourceCodeStart":440,"sourceCodeEnd":476,"githubUrl":"https://github.com/pnpm/pnpm/blob/5b11d3a15b9022a2109cb18ed96a5d652630371f/pnpm11/installing/deps-installer/src/install/extendInstallOptions.ts#L440-L476","documentation":"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.","triggerScenarios":"Install with lockfileOnly true and useLockfile false — for example `pnpm install --lockfile-only` while .npmrc or pnpm-workspace.yaml contains lockfile=false.","commonSituations":"A leftover `lockfile=false` from earlier experiments; a workspace where lockfiles are disabled but a CI job tries to regenerate one with --lockfile-only.","solutions":["Remove `lockfile=false` (or pass --lockfile) so the lockfile-only run can write pnpm-lock.yaml","If lockfiles must stay off, remove the --lockfile-only step from the pipeline"],"exampleFix":"# before (.npmrc)\nlockfile=false\n# pnpm install --lockfile-only fails with CONFIG_CONFLICT_LOCKFILE_ONLY_WITH_NO_LOCKFILE\n\n# after: delete the line, keep the job\n# lockfile=false\npnpm install --lockfile-only","handlingStrategy":"validation","validationCode":"export interface LockfileOpts { lockfileOnly?: boolean, useLockfile?: boolean }\n\nexport function lockfileOptsAreCoherent (opts: LockfileOpts): boolean {\n  return !(opts.lockfileOnly === true && opts.useLockfile === false)\n}\n// if (!lockfileOptsAreCoherent(parsedConfig)) fail fast with guidance","typeGuard":"import util from 'util'\nimport { PnpmError } from '@pnpm/error'\n\nexport const isLockfileOnlyConflictError = (err: unknown): err is PnpmError =>\n  util.types.isNativeError(err) && (err as PnpmError).code === 'CONFIG_CONFLICT_LOCKFILE_ONLY_WITH_NO_LOCKFILE'","tryCatchPattern":"try {\n  await mutateModules(mutations, opts)\n} catch (err) {\n  if (isLockfileOnlyConflictError(err)) {\n    throw new Error('remove lockfile=false or drop --lockfile-only', { cause: err })\n  }\n  throw err\n}","preventionTips":["Search the repo for `lockfile=false` before adding lockfile-related CI jobs","Prefer pnpm-workspace.yaml over scattered .npmrc for lockfile policy so one file holds the truth","Smoke-test config changes with `pnpm install --lockfile-only` locally"],"tags":["config","lockfile","conflict","install-options"],"backgroundTag":null,"analyzedSha":"5b11d3a15b9022a2109cb18ed96a5d652630371f","analyzedAt":"2026-08-16T13:18:59.198Z","schemaVersion":2},"datasetVersion":"2026-08-16T18:17:16.020Z"}