{"record":{"id":"2e944939fc53febb","repo":"pnpm/pnpm","slug":"team-invalid-scope","errorCode":"TEAM_INVALID_SCOPE","errorMessage":"Team spec must start with @scope, got \"${spec}\". Use @scope or @scope:team format.","messagePattern":"Team spec must start with @scope, got \"(.+?)\"\\. Use @scope or @scope:team format\\.","errorType":"validation","errorClass":"PnpmError","httpStatus":null,"severity":"error","filePath":"pnpm11/registry-access/commands/src/team.ts","lineNumber":389,"sourceCode":"\n  if (members.length === 0) {\n    return `@${scope}:${team} has no members`\n  }\n\n  const lines: string[] = [`@${scope}:${team} has the following members:`]\n  for (const { name } of members) {\n    lines.push(`  ${name}`)\n  }\n  return lines.join('\\n')\n}\n\n/**\n * Parse a scope:team string. Returns the scope (without @) and optional team name.\n * Format: @scope or @scope:team\n */\nfunction parseScopeTeam (spec: string): { scope: string, team?: string } {\n  if (!spec.startsWith('@')) {\n    throw new PnpmError('TEAM_INVALID_SCOPE',\n      `Team spec must start with @scope, got \"${spec}\". Use @scope or @scope:team format.`)\n  }\n\n  const inner = spec.slice(1)\n  if (!inner) {\n    throw new PnpmError('TEAM_INVALID_SCOPE',\n      `Team spec must start with @scope, got \"${spec}\". Use @scope or @scope:team format.`)\n  }\n\n  const colonIndex = inner.indexOf(':')\n  if (colonIndex === -1) {\n    return { scope: inner }\n  }\n  const scope = inner.slice(0, colonIndex)\n  const team = inner.slice(colonIndex + 1)\n  if (!scope || !team) {\n    throw new PnpmError('TEAM_INVALID_SCOPE',\n      `Team spec must start with @scope, got \"${spec}\". Use @scope or @scope:team format.`)","sourceCodeStart":371,"sourceCodeEnd":407,"githubUrl":"https://github.com/pnpm/pnpm/blob/6261b7f388016d57ca6b90340342411cd1d0d00f/pnpm11/registry-access/commands/src/team.ts#L371-L407","documentation":"`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.","triggerScenarios":"`pnpm team create org:team` (no leading @); `pnpm team ls org`; a script building the spec from a variable that already stripped the @.","commonSituations":"Muscle memory from unscoped package names; automation that normalizes scope names by removing @.","solutions":["Prefix the spec with @: `pnpm team ls @org:team`.","When building specs programmatically, keep the @: `'@' + scope + ':' + team`."],"exampleFix":"// before\npnpm team ls org:team\n\n// after\npnpm team ls @org:team","handlingStrategy":"type-guard","validationCode":"if (!spec.startsWith('@')) {\n  spec = `@${spec}` // or reject: throw new Error(`scope must start with @: ${spec}`)\n}","typeGuard":"function isScopedSpec (spec: string): boolean {\n  return spec.startsWith('@') && spec.length > 1\n}","tryCatchPattern":"try {\n  await teamHandler(opts, [subcommand, spec])\n} catch (err: any) {\n  if (err?.code === 'TEAM_INVALID_SCOPE') {\n    // re-prompt with the @scope[:team] format hint from the message\n  }\n  throw err\n}","preventionTips":["Normalize specs to start with @ before passing them to team commands.","Never strip the @ when storing scopes in config."],"tags":["cli","usage","team","scope-format"],"backgroundTag":"invalid-scope-format","analyzedSha":"6261b7f388016d57ca6b90340342411cd1d0d00f","analyzedAt":"2026-08-17T18:30:54.750Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}