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

  1. Pass --force to overwrite the existing agent file
  2. Choose a different agent name
  3. 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

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


AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27). Data as JSON: /api/errors/3e7c791e38af8dc8. Report an issue: GitHub.