Yeachan-Heo/oh-my-codex · error · Error
agent already exists: ${path}
Error message
agent already exists: ${path} What it means
addNativeAgent refuses to overwrite an existing agent file at the resolved path unless options.force is true. The path depends on scope: project scope resolves under .codex/agents in the repo, user scope under the home directory.
Source
Thrown at src/cli/agents.ts:174
): Promise<NativeAgentInfo[]> {
if (scope) return readScopeAgents(scope, cwd);
const [projectAgents, userAgents] = await Promise.all([
readScopeAgents('project', cwd),
readScopeAgents('user', cwd),
]);
return [...projectAgents, ...userAgents].sort((a, b) => a.name.localeCompare(b.name) || a.scope.localeCompare(b.scope));
}
async function addNativeAgent(
name: string,
options: { cwd?: string; scope?: AgentScope; force?: boolean } = {},
): Promise<string> {
const cwd = options.cwd ?? process.cwd();
const scope = options.scope ?? inferMutationScope(cwd);
const normalized = normalizeAgentName(name);
const path = getAgentFilePath(normalized, scope, cwd);
if (existsSync(path) && !options.force) {
throw new Error(`agent already exists: ${path}`);
}
await mkdir(resolveAgentsDir(scope, cwd), { recursive: true });
await writeFile(path, scaffoldAgentToml(normalized));
return path;
}
function resolveExistingAgentPath(
name: string,
options: { cwd?: string; scope?: AgentScope } = {},
): string {
const cwd = options.cwd ?? process.cwd();
const normalized = normalizeAgentName(name);
const candidateScopes: AgentScope[] = options.scope ? [options.scope] : ['project', 'user'];
for (const scope of candidateScopes) {
const path = getAgentFilePath(normalized, scope, cwd);
if (existsSync(path)) return path;
}
throw new Error(`agent not found: ${normalized}`);View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Pass --force to overwrite the existing agent file
- Choose a different agent name
- Remove the existing agent first (agent remove)
Example fix
# before omx agent add reviewer # after omx agent add reviewer --force
Defensive patterns
Strategy: try-catch
Validate before calling
import { existsSync } from 'node:fs';
if (existsSync(path) && !force) {
// decide: overwrite with force:true, pick another name, or abort
} Try / catch
try {
await addNativeAgent(name, { force: shouldOverwrite });
} catch (e) {
if (e instanceof Error && e.message.startsWith('agent already exists:')) {
await addNativeAgent(name, { force: true }); // deliberate overwrite
} else throw e;
} Prevention
- Make scaffolding scripts idempotent by passing --force when overwrite is intended
- Check existence first and branch on it
- Use unique per-team agent names to avoid project-scope collisions from git
When it happens
Trigger: Running the same `agent add` twice, or adding an agent whose TOML file already exists in the chosen scope.
Common situations: Re-running scaffolding scripts, agents created by teammates and pulled via git (project scope), or forgetting a previous add succeeded.
Related errors
- agent name must not be empty
- invalid agent name: ${name}
- \"${trimmed}\" is reserved by Codex built-in agents
- Expected --scope user|project
- agent not found: ${normalized}
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/3e7c791e38af8dc8.
Report an issue: GitHub.