Yeachan-Heo/oh-my-codex · error · Error
[ask] invalid --agent-prompt role "${role}". Expected lowerc
Error message
[ask] invalid --agent-prompt role "${role}". Expected lowercase role names like "executor" or "test-engineer". What it means
`omx ask --agent-prompt <role>` validates the role against SAFE_ROLE_PATTERN (lowercase alphanumeric/hyphen names) before touching the filesystem, as a path-traversal guard. Any role containing uppercase, slashes, dots, or other characters fails immediately with this error.
Source
Thrown at src/cli/ask.ts:63
const parsed = JSON.parse(readFileSync(scopePath, 'utf-8')) as Partial<{ scope: string }>;
if (parsed.scope === 'project' || parsed.scope === 'project-local') {
return join(cwd, '.codex', 'prompts');
}
}
} catch {
// Ignore malformed persisted scope and fall back to user prompts.
}
return codexPromptsDir();
}
async function resolveAgentPromptContent(
role: string,
promptsDir: string,
): Promise<string> {
const normalizedRole = role.trim().toLowerCase();
if (!SAFE_ROLE_PATTERN.test(normalizedRole)) {
throw new Error(`[ask] invalid --agent-prompt role "${role}". Expected lowercase role names like "executor" or "test-engineer".`);
}
if (!existsSync(promptsDir)) {
throw new Error(`[ask] prompts directory not found: ${promptsDir}. Run "omx setup" to install prompts.`);
}
const promptPath = join(promptsDir, `${normalizedRole}.md`);
if (!existsSync(promptPath)) {
const files = await readdir(promptsDir).catch(() => [] as string[]);
const availableRoles = files
.filter((file) => file.endsWith('.md'))
.map((file) => file.slice(0, -3))
.sort();
const availableSuffix = availableRoles.length > 0
? ` Available roles: ${availableRoles.join(', ')}.`
: '';
throw new Error(`[ask] --agent-prompt role "${normalizedRole}" not found in ${promptsDir}.${availableSuffix}`);
}View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Use lowercase hyphenated role names, e.g. `--agent-prompt executor` or `--agent-prompt test-engineer`
- Trim whitespace and remove special characters from the role string in calling scripts
- Sanitize user-supplied roles before passing them: lowercase and strip invalid characters
Example fix
# before omx ask --agent-prompt "Test Engineer" "do work" # after omx ask --agent-prompt test-engineer "do work"
Defensive patterns
Strategy: validation
Validate before calling
const SAFE = /^[a-z0-9]+(-[a-z0-9]+)*$/;
const role = String(rawRole).trim().toLowerCase();
if (!SAFE.test(role)) throw new Error('role must be lowercase-hyphen'); Type guard
const isSafeRole = (r: string): r is string => /^[a-z0-9]+(-[a-z0-9]+)*$/.test(r.trim());
Try / catch
catch (e) { if (/invalid --agent-prompt role/.test(String(e))) { promptUserForValidRole(); } else throw e; } Prevention
- Normalize roles to lowercase-hyphen before passing
- Never interpolate raw user input into --agent-prompt
- Maintain a typed union of known roles in your app
When it happens
Trigger: Passing `--agent-prompt Executor`, `--agent-prompt ../secrets`, `--agent-prompt test_engineer` (underscore if not allowed), or any role that does not match the safe-name regex.
Common situations: Users typing natural role names with capitals or spaces; scripts interpolating user input into the flag; attempted path traversal via the role argument.
Related errors
- Unknown adapt argument: ${arg}
- Unknown adapt subcommand: ${subcommand}. Supported subcomman
- agents-init accepts at most one path argument.\n${AGENTS_INI
- agent name must not be empty
- invalid agent name: ${name}
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/e4c831de2f7363d6.
Report an issue: GitHub.