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

agentTypes length must be 1 or ${workerCount}; received ${pr

Error message

agentTypes length must be 1 or ${workerCount}; received ${providers.length}.

What it means

normalizeAgentTypes requires the provider array length to be exactly 1 (broadcast to all workers) or exactly workerCount (per-worker assignment). Any other length — 0, 2 when there are 3 workers, or more than workerCount — throws this error. It fires only after all entries pass the codex|claude|gemini check.

Source

Thrown at src/team/runtime-cli.ts:221

  const status = phase === 'complete' ? 'completed' : 'failed';
  return {
    output: buildCliOutput(stateRoot, teamName, status, workerCount, startTimeMs),
    exitCode: status === 'completed' ? 0 : 1,
    notice:
      `[runtime-cli] phase=${phase} reached terminal state; preserving team state for inspection. `
      + `Inspect with "omx team status ${teamName} --json" or "omx team api read-stall-state --input '{\"team_name\":\"${teamName}\"}' --json". `
      + `Run "omx team shutdown ${teamName}" (or --force after state capture) when explicit cleanup is desired.\n`,
  };
}

export function normalizeAgentTypes(raw: string[], workerCount: number): TeamWorkerProvider[] {
  const providers = raw.map((entry) => String(entry || '').trim().toLowerCase());
  const invalid = providers.filter((entry) => entry !== 'codex' && entry !== 'claude' && entry !== 'gemini');
  if (invalid.length > 0) {
    throw new Error(`Invalid agentTypes entries: ${invalid.join(', ')}. Expected codex|claude|gemini.`);
  }
  if (providers.length !== 1 && providers.length !== workerCount) {
    throw new Error(`agentTypes length must be 1 or ${workerCount}; received ${providers.length}.`);
  }
  return providers as TeamWorkerProvider[];
}

export function resolveRuntimeCliProviderMap(
  raw: string[] | undefined,
  workerCount: number,
): string | null {
  if (!Array.isArray(raw) || raw.length === 0) {
    return null;
  }
  return normalizeAgentTypes(raw, workerCount).join(',');
}

export function resolveRuntimeCliAgentType(raw: string | undefined): string {
  const normalized = typeof raw === 'string' ? raw.trim() : '';
  return normalized || 'executor';
}

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Pass a single entry to use the same provider for all workers, or exactly one entry per worker
  2. Verify workerCount matches the number of --workers actually configured
  3. Default to replicating a single entry across all workers before calling

Example fix

// before
const providers = normalizeAgentTypes(['codex','claude'], 3);
// after
const raw = ['codex','claude'];
const providers = normalizeAgentTypes(raw.length === 1 ? raw : Array.from({length: 3}, (_, i) => raw[i % raw.length]), 3);
Defensive patterns

Strategy: validation

Validate before calling

if (raw.length !== 1 && raw.length !== workerCount) {
  raw = raw.length > 0 ? Array.from({length: workerCount}, (_, i) => raw[i % raw.length]) : ['codex'];
}

Try / catch

try { normalizeAgentTypes(raw, workerCount); } catch (e) { if (e instanceof Error && e.message.startsWith('agentTypes length')) { /* fill or trim to workerCount */ } throw e; }

Prevention

When it happens

Trigger: Passing 2 entries with workerCount 3, or an empty array (length 0 is neither 1 nor workerCount unless workerCount is 0).

Common situations: CLI flag lists fewer providers than --workers; partial config merge dropping entries; default worker count changed between versions making a previously valid array invalid.

Related errors


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