pnpm/pnpm · error · PnpmError

TEAM_INVALID_SCOPE

TEAM_INVALID_SCOPE

Error message

Team spec must start with @scope, got "${spec}". Use @scope or @scope:team format.

What it means

`parseScopeTeam` requires the spec to start with `@`. This variant fires when the leading @ is missing entirely (e.g. `org:team` or a bare `org`), so the string cannot be interpreted as an npm scope at all.

Source

Thrown at pnpm11/registry-access/commands/src/team.ts:389

  if (members.length === 0) {
    return `@${scope}:${team} has no members`
  }

  const lines: string[] = [`@${scope}:${team} has the following members:`]
  for (const { name } of members) {
    lines.push(`  ${name}`)
  }
  return lines.join('\n')
}

/**
 * Parse a scope:team string. Returns the scope (without @) and optional team name.
 * Format: @scope or @scope:team
 */
function parseScopeTeam (spec: string): { scope: string, team?: string } {
  if (!spec.startsWith('@')) {
    throw new PnpmError('TEAM_INVALID_SCOPE',
      `Team spec must start with @scope, got "${spec}". Use @scope or @scope:team format.`)
  }

  const inner = spec.slice(1)
  if (!inner) {
    throw new PnpmError('TEAM_INVALID_SCOPE',
      `Team spec must start with @scope, got "${spec}". Use @scope or @scope:team format.`)
  }

  const colonIndex = inner.indexOf(':')
  if (colonIndex === -1) {
    return { scope: inner }
  }
  const scope = inner.slice(0, colonIndex)
  const team = inner.slice(colonIndex + 1)
  if (!scope || !team) {
    throw new PnpmError('TEAM_INVALID_SCOPE',
      `Team spec must start with @scope, got "${spec}". Use @scope or @scope:team format.`)

View on GitHub (pinned to 6261b7f388)

Solutions

  1. Prefix the spec with @: `pnpm team ls @org:team`.
  2. When building specs programmatically, keep the @: `'@' + scope + ':' + team`.

Example fix

// before
pnpm team ls org:team

// after
pnpm team ls @org:team
Defensive patterns

Strategy: type-guard

Validate before calling

if (!spec.startsWith('@')) {
  spec = `@${spec}` // or reject: throw new Error(`scope must start with @: ${spec}`)
}

Type guard

function isScopedSpec (spec: string): boolean {
  return spec.startsWith('@') && spec.length > 1
}

Try / catch

try {
  await teamHandler(opts, [subcommand, spec])
} catch (err: any) {
  if (err?.code === 'TEAM_INVALID_SCOPE') {
    // re-prompt with the @scope[:team] format hint from the message
  }
  throw err
}

Prevention

When it happens

Trigger: `pnpm team create org:team` (no leading @); `pnpm team ls org`; a script building the spec from a variable that already stripped the @.

Common situations: Muscle memory from unscoped package names; automation that normalizes scope names by removing @.

Related errors


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