Yeachan-Heo/oh-my-codex · error · Error

Invalid team_name: "${rawTeamName}". Must match /^[a-z0-9][a

Error message

Invalid team_name: "${rawTeamName}". Must match /^[a-z0-9][a-z0-9-]{0,29}$/ or resolve to an existing display name.

What it means

Thrown during display-name resolution: the team_name neither matches the strict safe pattern nor resolves to any known display/requested name in the current workspace (via listTeamLookupCandidates). It means the team is unknown to this repository's state.

Source

Thrown at src/team/api-interop.ts:604

function normalizeTeamDisplayLookupName(value: string): string {
  return value
    .toLowerCase()
    .replace(/[^a-z0-9]+/g, '-')
    .replace(/-+/g, '-')
    .replace(/^-|-$/g, '')
    .slice(0, 30)
    .replace(/-$/, '');
}

function assertUnsafeTeamNameMatchesKnownDisplay(rawTeamName: string, cwd: string): void {
  if (TEAM_NAME_SAFE_PATTERN.test(rawTeamName)) return;
  const normalized = normalizeTeamDisplayLookupName(rawTeamName);
  const matchesKnownDisplay = listTeamLookupCandidates(cwd).some((candidate) => {
    return normalizeTeamDisplayLookupName(candidate.displayName) === normalized
      || normalizeTeamDisplayLookupName(candidate.requestedName) === normalized;
  });
  if (!matchesKnownDisplay) {
    throw new Error(`Invalid team_name: "${rawTeamName}". Must match /^[a-z0-9][a-z0-9-]{0,29}$/ or resolve to an existing display name.`);
  }
}

export async function executeTeamApiOperation(
  operation: TeamApiOperation,
  args: Record<string, unknown>,
  fallbackCwd: string,
): Promise<TeamApiEnvelope> {
  try {
    validateCommonFields(args, { skipTeamName: true });
    const rawTeamNameForCwd = String(args.team_name || '').trim();
    if (rawTeamNameForCwd) assertUnsafeTeamNameMatchesKnownDisplay(rawTeamNameForCwd, fallbackCwd);
    const resolvedTeamName = rawTeamNameForCwd ? resolveTeamNameForCurrentContext(rawTeamNameForCwd, fallbackCwd) : '';
    const cwd = resolvedTeamName ? resolveTeamWorkingDirectory(resolvedTeamName, fallbackCwd) : fallbackCwd;
    const opArgs = resolvedTeamName ? { ...args, team_name: resolvedTeamName } : args;
    validateCommonFields(opArgs);

    switch (operation) {

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Run from the repository root where the team state exists
  2. List available team lookup candidates to find the exact accepted name
  3. Fall back to the team's canonical slug matching the safe pattern

Example fix

// before
api('status', { team_name: 'My Team' }); // unknown in this cwd
// after
const cands = listTeamLookupCandidates(cwd); // pick exact displayName
api('status', { team_name: cands[0].displayName });
Defensive patterns

Strategy: fallback

Validate before calling

const known = listTeamLookupCandidates(cwd);
const ok = /^[a-z0-9][a-z0-9-]{0,29}$/.test(name)
  || known.some((c) => c.displayName === name || c.requestedName === name);
if (!ok) throw new Error('unknown team name');

Try / catch

catch (e) { if (/or resolve to an existing display name/.test(e.message)) { const cands = listTeamLookupCandidates(cwd); /* pick or create team */ } }

Prevention

When it happens

Trigger: Passing a human-readable team name that was never registered/persisted in the workspace, or a typo, or running from the wrong cwd where the team candidates are not listed.

Common situations: Running the API from a different working directory than where the team was created; stale workspace state after cleanup; typo in display name casing/punctuation.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27). Data as JSON: /api/errors/9623a7a47d5709e1. Report an issue: GitHub.