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
- Pass a single entry to use the same provider for all workers, or exactly one entry per worker
- Verify workerCount matches the number of --workers actually configured
- 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
- Derive provider list length from the same source as workerCount
- Default to a single provider entry when unspecified
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
- Invalid agentTypes entries: ${invalid.join(', ')}. Expected
- Missing JSON payload for ${RUNTIME_CLI_INPUT_JSON_FLAG}
- Missing JSON payload for ${RUNTIME_CLI_INPUT_JSON_BASE64_FLA
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/32ec3bc97beb637b.
Report an issue: GitHub.