ruvnet/ruflo · error · Error
invalid ${label}: ${value}
Error message
invalid ${label}: ${value} What it means
The worktree coordinator uses assertId() to validate run ids and agent ids against SAFE_ID = /^[a-z0-9][a-z0-9._-]{0,63}$/: lowercase alphanumerics, dots, underscores, hyphens; must start with a letter/digit; max 64 chars. Ids become directory names and registry keys, so anything else (uppercase, slashes, '..', spaces, unicode, empty, >64 chars) is rejected with 'invalid <run id|agent id>: <value>'.
Source
Thrown at v3/@claude-flow/codex/src/worktrees/coordinator.ts:31
export interface WorktreeRunRecord {
version: 1;
runId: string;
repoRoot: string;
createdAt: number;
assignments: WorktreeAssignment[];
}
function git(repoRoot: string, args: string[]): string {
return execFileSync('git', ['-C', repoRoot, ...args], {
encoding: 'utf8',
stdio: ['ignore', 'pipe', 'pipe'],
maxBuffer: 4 * 1024 * 1024,
}).trim();
}
function assertId(value: string, label: string): void {
if (!SAFE_ID.test(value)) throw new Error(`invalid ${label}: ${value}`);
}
export class CodexWorktreeCoordinator {
readonly repoRoot: string;
readonly registryDir: string;
readonly worktreeBase: string;
constructor(repoRoot: string) {
this.repoRoot = resolve(repoRoot);
const top = git(this.repoRoot, ['rev-parse', '--show-toplevel']);
if (resolve(top) !== this.repoRoot) throw new Error(`repoRoot must be the git top-level: ${top}`);
this.registryDir = join(this.repoRoot, '.claude-flow', 'swarm', 'worktrees');
this.worktreeBase = join(dirname(this.repoRoot), '.ruflo-worktrees', basename(this.repoRoot));
}
prepare(
runId: string,
agents: Array<{ id: string; readOnly?: boolean }>,View on GitHub (pinned to fa13ee4ad6)
Solutions
- Normalize ids before calling: lowercase, replace unsafe chars with '-', trim to 64 chars, ensure it starts with [a-z0-9]
- Prefer short slugs like 'agent-1', 'coder-2', 'run-20260818'
- Validate in your own code with the same regex so the error surfaces at the source
Example fix
// before
coordinator.prepare('Run #1', [{ id: 'Coder/Alpha' }]); // throws
// after
const SAFE_ID = /^[a-z0-9][a-z0-9._-]{0,63}$/;
const slug = (s: string) => s.toLowerCase().replace(/[^a-z0-9._-]+/g, '-').slice(0, 64);
coordinator.prepare(slug('run-1'), [{ id: slug('coder-alpha') }]); Defensive patterns
Strategy: type-guard
Validate before calling
const SAFE_ID = /^[a-z0-9][a-z0-9._-]{0,63}$/;
const okId = (s: string) => SAFE_ID.test(s); Type guard
const SAFE_ID = /^[a-z0-9][a-z0-9._-]{0,63}$/;
function isSafeId(v: unknown): v is string {
return typeof v === 'string' && SAFE_ID.test(v);
} Try / catch
try { coordinator.prepare(runId, agents); } catch (e) { if (/^invalid (run|agent) id/.test(String(e))) throw new TypeError(`normalize ids: ${e.message}`); throw e; } Prevention
- Generate ids as slugs: lowercase, [a-z0-9._-], <=64 chars, leading letter/digit
- Never reuse display names, uuids, or branch names as agent ids unchecked
- Slugify at the boundary where human names become machine ids
When it happens
Trigger: prepare('Run/1', ...) or agent ids like 'Agent Alpha', '../escape', 'Ünicode-id', '', or a 70-char id; ids generated with uuid (uppercase hex) or containing path separators.
Common situations: Callers reuse display names or uuids as agent ids; ids derived from branch names with slashes; usernames with spaces; accidental uppercase from copy-paste.
Related errors
- Validation failed: ${result.error}
- ${toolsJson} must contain a JSON array of {name, description
- basePath contains disallowed characters
- memory path contains disallowed characters
- label may only contain [A-Za-z0-9_.\\-:/@]
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/15a5c7de8a76596b.
Report an issue: GitHub.