pnpm/pnpm · error · PnpmError

VERSIONING_UNRELEASABLE_PACKAGE

VERSIONING_UNRELEASABLE_PACKAGE

Error message

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".

What it means

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.

Source

Thrown at pnpm11/releasing/versioning/src/assembleReleasePlan.ts:650

): Map<string, Map<string, IntentBumpType>> {
  const intentBumps = new Map<string, Map<string, IntentBumpType>>()
  for (const intent of intents) {
    const byDir = new Map<string, IntentBumpType>()
    for (const [ref, bumpType] of Object.entries(intent.releases)) {
      const dirs = refs.refToDirs(ref)
      if (dirs.length === 0) {
        throw new PnpmError('VERSIONING_UNKNOWN_PACKAGE', `Change intent file ${intent.filePath} names ${ref}, which is not a package in this workspace`)
      }
      if (dirs.length > 1) {
        throw new PnpmError(
          'VERSIONING_AMBIGUOUS_PACKAGE',
          `Change intent file ${intent.filePath} names ${ref}, which matches multiple workspace projects: ${dirs.map((dir) => `./${dir}`).join(', ')}. ` +
          'Reference the project by directory instead, e.g. "./' + dirs[0] + '": ' + bumpType
        )
      }
      const dir = dirs[0]
      if (bumpType !== 'none' && !participants.has(dir)) {
        throw new PnpmError(
          'VERSIONING_UNRELEASABLE_PACKAGE',
          `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".'
        )
      }
      const existing = byDir.get(dir)
      if (existing == null || (bumpType !== 'none' && BUMP_ORDER[bumpType] > (existing === 'none' ? 0 : BUMP_ORDER[existing]))) {
        byDir.set(dir, bumpType)
      }
    }
    intentBumps.set(intent.id, byDir)
  }
  return intentBumps
}

function assertInternalDepsUseWorkspaceProtocol (participants: Map<string, Participant>): void {
  for (const participant of participants.values()) {

View on GitHub (pinned to 6261b7f388)

Solutions

  1. Change the entry to "none" (records the change without releasing) or delete the entry from the intent file
  2. Remove the package from versioning.ignore in pnpm-workspace.yaml if it should actually release
  3. Give the package a valid semver version field in its package.json

Example fix

# .changeset/quiet-otter.md — before
---
"internal-tools": patch
---
Tweak script

# after
---
"internal-tools": none
---
Tweak script
Defensive patterns

Strategy: validation

Validate before calling

import semver from 'semver'

// Check release eligibility before writing a bump for a package.
export function isReleasable (pkg: { name: string, dir: string, version?: string }, ignore: string[]): boolean {
  if (ignore.includes(pkg.name) || ignore.includes(`./${pkg.dir}`)) return false
  return pkg.version != null && semver.valid(pkg.version) != null
}

Try / catch

try {
  await assembleReleasePlan(opts)
} catch (err) {
  if (err instanceof PnpmError && err.code === 'VERSIONING_UNRELEASABLE_PACKAGE') {
    // Either drop the entry, set it to "none", or make the package releasable
    throw new Error(`Intent targets an unreleasable package: ${err.message}`)
  }
  throw err
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of pnpm/pnpm@6261b7f388 (2026-08-17). Data as JSON: /api/errors/f076de2294a62b3d. Report an issue: GitHub.