{"record":{"id":"f076de2294a62b3d","repo":"pnpm/pnpm","slug":"versioning-unreleasable-package","errorCode":"VERSIONING_UNRELEASABLE_PACKAGE","errorMessage":"Change intent file ${intent.filePath} requests a ${bumpType} release of ${ref}, which cannot release (it is listed in versioning.ignore, has no version field, or has a non-semver version). Remove the entry or change it to \"none\".","messagePattern":"Change intent file (.+?) requests a (.+?) release of (.+?), which cannot release \\(it is listed in versioning\\.ignore, has no version field, or has a non-semver version\\)\\. Remove the entry or change it to \"none\"\\.","errorType":"exception","errorClass":"PnpmError","httpStatus":null,"severity":"error","filePath":"pnpm11/releasing/versioning/src/assembleReleasePlan.ts","lineNumber":650,"sourceCode":"): Map<string, Map<string, IntentBumpType>> {\n  const intentBumps = new Map<string, Map<string, IntentBumpType>>()\n  for (const intent of intents) {\n    const byDir = new Map<string, IntentBumpType>()\n    for (const [ref, bumpType] of Object.entries(intent.releases)) {\n      const dirs = refs.refToDirs(ref)\n      if (dirs.length === 0) {\n        throw new PnpmError('VERSIONING_UNKNOWN_PACKAGE', `Change intent file ${intent.filePath} names ${ref}, which is not a package in this workspace`)\n      }\n      if (dirs.length > 1) {\n        throw new PnpmError(\n          'VERSIONING_AMBIGUOUS_PACKAGE',\n          `Change intent file ${intent.filePath} names ${ref}, which matches multiple workspace projects: ${dirs.map((dir) => `./${dir}`).join(', ')}. ` +\n          'Reference the project by directory instead, e.g. \"./' + dirs[0] + '\": ' + bumpType\n        )\n      }\n      const dir = dirs[0]\n      if (bumpType !== 'none' && !participants.has(dir)) {\n        throw new PnpmError(\n          'VERSIONING_UNRELEASABLE_PACKAGE',\n          `Change intent file ${intent.filePath} requests a ${bumpType} release of ${ref}, which cannot release ` +\n          '(it is listed in versioning.ignore, has no version field, or has a non-semver version). ' +\n          'Remove the entry or change it to \"none\".'\n        )\n      }\n      const existing = byDir.get(dir)\n      if (existing == null || (bumpType !== 'none' && BUMP_ORDER[bumpType] > (existing === 'none' ? 0 : BUMP_ORDER[existing]))) {\n        byDir.set(dir, bumpType)\n      }\n    }\n    intentBumps.set(intent.id, byDir)\n  }\n  return intentBumps\n}\n\nfunction assertInternalDepsUseWorkspaceProtocol (participants: Map<string, Participant>): void {\n  for (const participant of participants.values()) {","sourceCodeStart":632,"sourceCodeEnd":668,"githubUrl":"https://github.com/pnpm/pnpm/blob/6261b7f388016d57ca6b90340342411cd1d0d00f/pnpm11/releasing/versioning/src/assembleReleasePlan.ts#L632-L668","documentation":"Only 'participants' — projects eligible for release — may receive version bumps. A project is not a participant when it is listed in versioning.ignore, has no version field in its manifest, or its version is not valid semver. resolveIntents throws VERSIONING_UNRELEASABLE_PACKAGE when an intent requests a real bump (anything other than none) for such a project.","triggerScenarios":"An intent file entry with a bump type other than 'none' whose resolved directory is not in the participants map: the package is in versioning.ignore, has no version field, or its version is non-semver (e.g. '0.0.0-dev' is fine, 'next' or a git hash is not).","commonSituations":"Intent files written for private/internal packages that were later added to versioning.ignore; packages with a placeholder or missing version field; templates that bump every changed package.","solutions":["Change the entry to \"none\" (records the change without releasing) or delete the entry from the intent file","Remove the package from versioning.ignore in pnpm-workspace.yaml if it should actually release","Give the package a valid semver version field in its package.json"],"exampleFix":"# .changeset/quiet-otter.md — before\n---\n\"internal-tools\": patch\n---\nTweak script\n\n# after\n---\n\"internal-tools\": none\n---\nTweak script","handlingStrategy":"validation","validationCode":"import semver from 'semver'\n\n// Check release eligibility before writing a bump for a package.\nexport function isReleasable (pkg: { name: string, dir: string, version?: string }, ignore: string[]): boolean {\n  if (ignore.includes(pkg.name) || ignore.includes(`./${pkg.dir}`)) return false\n  return pkg.version != null && semver.valid(pkg.version) != null\n}","typeGuard":null,"tryCatchPattern":"try {\n  await assembleReleasePlan(opts)\n} catch (err) {\n  if (err instanceof PnpmError && err.code === 'VERSIONING_UNRELEASABLE_PACKAGE') {\n    // Either drop the entry, set it to \"none\", or make the package releasable\n    throw new Error(`Intent targets an unreleasable package: ${err.message}`)\n  }\n  throw err\n}","preventionTips":["Give every workspace package a valid semver version field, even private ones","Keep versioning.ignore in sync with packages you stop releasing, and clean their pending intents","In intent-generating tooling, filter targets through an eligibility check like the one above"],"tags":["versioning","change-intent","semver","workspace"],"backgroundTag":"non-releasable-package","analyzedSha":"6261b7f388016d57ca6b90340342411cd1d0d00f","analyzedAt":"2026-08-17T18:30:54.750Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}