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

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

Error message

Invalid team_name: "${teamName}". Must match /^[a-z0-9][a-z0-9-]{0,29}$/ (lowercase alphanumeric + hyphens, max 30 chars).

What it means

validateCommonFields throws this when a non-empty team_name fails TEAM_NAME_SAFE_PATTERN (/^[a-z0-9][a-z0-9-]{0,29}$/). Team names must be lowercase alphanumeric plus hyphens, start alphanumeric, max 30 chars — a safety constraint for filesystem and CLI usage.

Source

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

export function resolveTeamApiOperation(name: string): TeamApiOperation | null {
  const normalized = normalizeTeamName(name);
  return TEAM_API_OPERATIONS.includes(normalized as TeamApiOperation) ? (normalized as TeamApiOperation) : null;
}

export function buildLegacyTeamDeprecationHint(legacyName: string, originalArgs?: Record<string, unknown>): string {
  const operation = resolveTeamApiOperation(legacyName);
  const payload = JSON.stringify(originalArgs ?? {});
  if (!operation) {
    return `Use CLI interop: omx team api <operation> --input '${payload}' --json`;
  }
  return `Use CLI interop: omx team api ${operation} --input '${payload}' --json`;
}

function validateCommonFields(args: Record<string, unknown>, options: { skipTeamName?: boolean } = {}): void {
  const teamName = String(args.team_name || '').trim();
  if (!options.skipTeamName && teamName && !TEAM_NAME_SAFE_PATTERN.test(teamName)) {
    throw new Error(`Invalid team_name: "${teamName}". Must match /^[a-z0-9][a-z0-9-]{0,29}$/ (lowercase alphanumeric + hyphens, max 30 chars).`);
  }

  for (const workerField of ['worker', 'from_worker', 'to_worker']) {
    const workerVal = String(args[workerField] || '').trim();
    if (workerVal && !WORKER_NAME_SAFE_PATTERN.test(workerVal)) {
      throw new Error(`Invalid ${workerField}: "${workerVal}". Must match /^[a-z0-9][a-z0-9-]{0,63}$/ (lowercase alphanumeric + hyphens, max 64 chars).`);
    }
  }

  const rawTaskId = String(args.task_id || '').trim();
  if (rawTaskId && !TASK_ID_SAFE_PATTERN.test(rawTaskId)) {
    throw new Error(`Invalid task_id: "${rawTaskId}". Must be a positive integer (digits only, max 20 digits).`);
  }
}


function normalizeTeamDisplayLookupName(value: string): string {
  return value

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Lowercase the name and replace unsupported characters with hyphens
  2. Ensure the first character is a letter or digit (no leading hyphen)
  3. Trim the name to 30 characters or use the team's registered slug

Example fix

// before
api('status', { team_name: 'My_Team' });
// after
api('status', { team_name: 'my-team' });
Defensive patterns

Strategy: validation

Validate before calling

const TEAM = /^[a-z0-9][a-z0-9-]{0,29}$/;
const name = String(args.team_name || '').trim();
if (name && !TEAM.test(name)) throw new RangeError('team_name format invalid');

Type guard

const isSafeTeamName = (n: string): boolean => /^[a-z0-9][a-z0-9-]{0,29}$/.test(n);

Prevention

When it happens

Trigger: Calling executeTeamApiOperation with team_name containing uppercase letters, underscores, spaces, a leading hyphen, or exceeding 30 characters.

Common situations: Using a display name like 'My Team' as team_name; org names with underscores copied from CI config; hyphen-prefixed branch-derived names.

Related errors


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