Yeachan-Heo/oh-my-codex · error · Error
Invalid ${workerField}: "${workerVal}". Must match /^[a-z0-9
Error message
Invalid ${workerField}: "${workerVal}". Must match /^[a-z0-9][a-z0-9-]{0,63}$/ (lowercase alphanumeric + hyphens, max 64 chars). What it means
validateCommonFields throws this when worker, from_worker, or to_worker is non-empty and fails WORKER_NAME_SAFE_PATTERN (/^[a-z0-9][a-z0-9-]{0,63}$/). Worker names are constrained for safe CLI and path handling.
Source
Thrown at src/team/api-interop.ts:575
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
.toLowerCase()
.replace(/[^a-z0-9]+/g, '-')
.replace(/-+/g, '-')
.replace(/^-|-$/g, '')
.slice(0, 30)
.replace(/-$/, '');View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Normalize worker names to lowercase-alphanumeric-with-hyphens
- Check length <= 64 and that the first char is a letter/digit
- Regenerate worker names from the approved naming scheme rather than free-form input
Example fix
// before
api('send-message', { from_worker: 'Worker_1' });
// after
api('send-message', { from_worker: 'worker-1' }); Defensive patterns
Strategy: validation
Validate before calling
const WORKER = /^[a-z0-9][a-z0-9-]{0,63}$/;
for (const f of ['worker','from_worker','to_worker']) {
const v = String(args[f] || '').trim();
if (v && !WORKER.test(v)) throw new RangeError(`${f} format invalid`);
} Type guard
const isSafeWorkerName = (n: string): boolean => /^[a-z0-9][a-z0-9-]{0,63}$/.test(n); Prevention
- Generate worker names from a slugify helper, never free-form input
- Reject hostnames with dots before deriving worker names
When it happens
Trigger: Passing a worker field with uppercase, underscores, spaces, leading hyphen, or length over 64 characters to any team API operation.
Common situations: Worker names auto-generated from hostnames containing dots or underscores; renaming schemes that use CamelCase; copy-paste with trailing whitespace or newline.
Related errors
- Invalid team_name: "${teamName}". Must match /^[a-z0-9][a-z0
- invalid auth slot path
- Autoresearch goal ${mission.slug} cannot complete until prof
- autoresearch candidate artifact notes must be a string array
- autoresearch candidate artifact created_at is required
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/48bff5231cac235b.
Report an issue: GitHub.