pnpm/pnpm · error · PnpmError

PKG_UNKNOWN_SUBCOMMAND

PKG_UNKNOWN_SUBCOMMAND

Error message

Unknown subcommand "${subcmd}"

What it means

Thrown by the `pnpm pkg` command when its first positional argument is not one of the supported subcommands: `get`, `set`, `delete`, or `fix`. `runSubcommand`'s switch falls through to the default branch and raises this error with the full help text attached as a hint. It exists to catch typos and npm-style guesses before any manifest is read or written.

Source

Thrown at pnpm11/pkg-manifest/commands/src/pkg.ts:66

  if (opts.recursive) {
    return handleRecursiveCommand(opts, subcmd, args)
  }

  return runSubcommand(opts, subcmd, args)
}

async function runSubcommand (opts: PkgCommandOptions, subcmd: string, args: string[]): Promise<string | void> {
  switch (subcmd) {
    case 'get':
      return pkgGet(opts, args)
    case 'set':
      return pkgSet(opts, args)
    case 'delete':
      return pkgDelete(opts, args)
    case 'fix':
      return pkgFix(opts)
    default:
      throw new PnpmError('PKG_UNKNOWN_SUBCOMMAND', `Unknown subcommand "${subcmd}"`, {
        hint: help(),
      })
  }
}

async function handleRecursiveCommand (opts: PkgCommandOptions, subcmd: string, args: string[]): Promise<string | void> {
  const workspaceDir = opts.workspaceDir
  if (!workspaceDir) {
    throw new PnpmError('PKG_RECURSIVE_NO_ROOT', 'Cannot run recursively outside of a workspace')
  }

  const selectedProjects = opts.selectedProjectsGraph == null
    ? []
    : Object.values(opts.selectedProjectsGraph)

  if (selectedProjects.length === 0) {
    throw new PnpmError('PKG_RECURSIVE_NO_PACKAGES', 'No workspace packages were selected')
  }

View on GitHub (pinned to 6261b7f388)

Solutions

  1. Run `pnpm pkg help` and use one of the exact subcommands: get, set, delete, fix
  2. Fix the abbreviation - the remove subcommand is `delete`, not `del` or `remove`
  3. To read fields use `pnpm pkg get` (optionally with dotted key paths), not `list`
  4. Upgrade pnpm if `pnpm pkg fix` is reported as unknown on an old release

Example fix

# before
pnpm pkg del name

# after
pnpm pkg delete name
Defensive patterns

Strategy: validation

Validate before calling

const PKG_SUBCOMMANDS = new Set(['get', 'set', 'delete', 'fix'])

if (!PKG_SUBCOMMANDS.has(subcmd)) {
  console.error(`unknown pkg subcommand: ${subcmd}. Valid: get, set, delete, fix`)
  process.exitCode = 1
} else {
  await handler(opts, [subcmd, ...args])
}

Type guard

type PkgSubcommand = 'get' | 'set' | 'delete' | 'fix'

const isPkgSubcommand = (s: string): s is PkgSubcommand =>
  s === 'get' || s === 'set' || s === 'delete' || s === 'fix'

Try / catch

try {
  await runPnpm(['pkg', subcmd, ...args])
} catch (err) {
  if (err?.code === 'ERR_PNPM_PKG_UNKNOWN_SUBCOMMAND') {
    // print command help instead of a stack trace
  } else throw err
}

Prevention

When it happens

Trigger: Running `pnpm pkg <anything-other-than-get/set/delete/fix>`, e.g. `pnpm pkg del name` (wrong abbreviation), `pnpm pkg list`, or `pnpm pkg instal`. Also hit when a wrapper script passes an empty or mis-ordered first parameter so the subcommand token is missing or swallowed by a flag.

Common situations: Typo'ing `delete` as `del`/`remove`/`rm`; assuming npm-style subcommands like `list` exist; older pnpm releases that lack the `fix` subcommand; CI scripts that assemble the `pnpm pkg` argv dynamically.

Related errors


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