Yeachan-Heo/oh-my-codex · error · Error

agent not found: ${normalized}

Error message

agent not found: ${normalized}

What it means

remove/edit path resolution: resolveExistingAgentPath checks the candidate scope(s) (project then user, unless --scope narrows it) and throws when no agent file exists for the normalized name. It is the not-found guard before deletion or editing.

Source

Thrown at src/cli/agents.ts:192

    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}`);
}

async function confirmRemove(path: string): Promise<boolean> {
  const rl = createInterface({ input: process.stdin, output: process.stdout });
  try {
    const answer = (await rl.question(`Delete native agent ${path}? [y/N]: `)).trim().toLowerCase();
    return answer === 'y' || answer === 'yes';
  } finally {
    rl.close();
  }
}

function ensureInteractiveRemove(force: boolean): void {
  if (force) return;
  if (process.stdin.isTTY && process.stdout.isTTY) return;
  throw new Error('remove requires an interactive terminal; rerun with --force in non-interactive environments');
}

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. List agents to confirm the exact name (e.g. `omx agent list`)
  2. Omit --scope so both scopes are searched
  3. Check you are in the right working directory for project-scoped agents

Example fix

# before
omx agent remove reviwer --scope project

# after
omx agent remove reviewer
Defensive patterns

Strategy: validation

Validate before calling

import { existsSync } from 'node:fs';
const path = getAgentFilePath(name, 'project', cwd);
if (!existsSync(path) && !existsSync(getAgentFilePath(name, 'user', cwd))) {
  console.error(`no such agent: ${name}`);
  process.exit(2);
}

Try / catch

try {
  await removeNativeAgent(name);
} catch (e) {
  if (e instanceof Error && e.message.startsWith('agent not found:')) return; // already gone: treat as success
  throw e;
}

Prevention

When it happens

Trigger: `omx agent remove ghost`, editing a typo'd name, or removing with --scope project when the agent only exists in user scope.

Common situations: Typos, agent was already removed, wrong --scope narrowing the search, or running from a different directory so project scope resolves elsewhere.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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