Yeachan-Heo/oh-my-codex · error · Error
\"${trimmed}\" is reserved by Codex built-in agents
Error message
\"${trimmed}\" is reserved by Codex built-in agents What it means
The name, while syntactically valid, collides with a reserved Codex built-in agent name (RESERVED_NATIVE_AGENT_NAMES). Creating a user agent with one of these names would shadow or conflict with the built-in, so it is refused.
Source
Thrown at src/cli/agents.ts:51
name: string;
description: string;
model?: string;
}
function isReservedNativeAgentName(name: string): boolean {
return RESERVED_NATIVE_AGENT_NAMES.has(name.trim());
}
function normalizeAgentName(name: string): string {
const trimmed = name.trim();
if (!trimmed) {
throw new Error('agent name must not be empty');
}
if (!/^[A-Za-z0-9][A-Za-z0-9_-]*$/.test(trimmed)) {
throw new Error(`invalid agent name: ${name}`);
}
if (isReservedNativeAgentName(trimmed)) {
throw new Error(`"${trimmed}" is reserved by Codex built-in agents`);
}
return trimmed;
}
function resolveAgentsDir(scope: AgentScope, cwd = process.cwd()): string {
return scope === 'project' ? projectCodexAgentsDir(cwd) : codexAgentsDir();
}
function parseScopeArg(args: string[]): AgentScope | undefined {
for (let i = 0; i < args.length; i += 1) {
const arg = args[i];
if (arg === '--scope') {
const value = args[i + 1];
if (value === 'user' || value === 'project') return value;
throw new Error('Expected --scope user|project');
}
if (arg === '--scope=user') return 'user';
if (arg === '--scope=project') return 'project';View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Pick a different, more specific name (e.g. review-strict instead of review)
- Check the reserved names list in src/cli/agents.ts (RESERVED_NATIVE_AGENT_NAMES)
- Customize built-in behavior via supported configuration instead of shadowing the name
Example fix
# before omx agent add review # after omx agent add review-strict
Defensive patterns
Strategy: validation
Validate before calling
// Mirror RESERVED_NATIVE_AGENT_NAMES before calling add
import { isReservedNativeAgentName } from './agents';
if (isReservedNativeAgentName(candidate)) {
candidate = `${candidate}-custom`; // de-conflict
} Type guard
const isReservable = (n: string): boolean => !RESERVED_NATIVE_AGENT_NAMES.has(n.trim());
Try / catch
try { await addNativeAgent(name); } catch (e) { if (/reserved by Codex built-in/.test(String(e))) name = `${name}-x`; else throw e; } Prevention
- Prefix custom agents with a project or team qualifier
- Never try to shadow built-in agent names
When it happens
Trigger: addNativeAgent('review'), addNativeAgent('plan') or any other name in the reserved set (typically short built-in verbs like review/plan).
Common situations: Users trying to override or customize a built-in agent by creating a same-named native agent.
Related errors
- agent name must not be empty
- invalid agent name: ${name}
- catalog_manifest_invalid:agents[${index}]
- catalog_manifest_invalid:agents[${index}].category
- catalog_manifest_invalid:agents[${index}].status
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/19f9af34e6f107cd.
Report an issue: GitHub.