{"record":{"id":"25f41942d6b17456","repo":"Yeachan-Heo/oh-my-codex","slug":"invalid-agent-name-name","errorCode":null,"errorMessage":"invalid agent name: ${name}","messagePattern":"invalid agent name: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/cli/agents.ts","lineNumber":48,"sourceCode":"  scope: AgentScope;\n  path: string;\n  file: string;\n  name: string;\n  description: string;\n  model?: string;\n}\n\nfunction isReservedNativeAgentName(name: string): boolean {\n  return RESERVED_NATIVE_AGENT_NAMES.has(name.trim());\n}\n\nfunction normalizeAgentName(name: string): string {\n  const trimmed = name.trim();\n  if (!trimmed) {\n    throw new Error('agent name must not be empty');\n  }\n  if (!/^[A-Za-z0-9][A-Za-z0-9_-]*$/.test(trimmed)) {\n    throw new Error(`invalid agent name: ${name}`);\n  }\n  if (isReservedNativeAgentName(trimmed)) {\n    throw new Error(`\"${trimmed}\" is reserved by Codex built-in agents`);\n  }\n  return trimmed;\n}\n\nfunction resolveAgentsDir(scope: AgentScope, cwd = process.cwd()): string {\n  return scope === 'project' ? projectCodexAgentsDir(cwd) : codexAgentsDir();\n}\n\nfunction parseScopeArg(args: string[]): AgentScope | undefined {\n  for (let i = 0; i < args.length; i += 1) {\n    const arg = args[i];\n    if (arg === '--scope') {\n      const value = args[i + 1];\n      if (value === 'user' || value === 'project') return value;\n      throw new Error('Expected --scope user|project');","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/cli/agents.ts#L30-L66","documentation":"The agent name fails the pattern ^[A-Za-z0-9][A-Za-z0-9_-]*$: it must start with an alphanumeric character and may only contain letters, digits, underscores and hyphens. Spaces, dots, slashes, leading hyphens/underscores, or unicode characters are rejected because the name becomes a TOML filename and identifier.","triggerScenarios":"addNativeAgent('my agent.toml'), addNativeAgent('-ops'), addNativeAgent('rev/iew'), or names with spaces passed unquoted through the shell.","commonSituations":"Descriptive names with spaces ('code reviewer'), file extensions included, path separators, or copy-pasted display names used as identifiers.","solutions":["Rewrite the name using only A-Z a-z 0-9 _ - starting with a letter or digit","Remove file extensions and path separators","Quote shell arguments so spaces do not split — then remove the spaces"],"exampleFix":"# before\nomx agent add \"code reviewer\"\n\n# after\nomx agent add code-reviewer","handlingStrategy":"type-guard","validationCode":"const NAME_RE = /^[A-Za-z0-9][A-Za-z0-9_-]*$/;\nif (!NAME_RE.test(name.trim())) {\n  console.error('agent name must be alphanumeric/underscore/hyphen, starting alphanumeric');\n  process.exit(2);\n}","typeGuard":"const isValidAgentName = (n: string): boolean => /^[A-Za-z0-9][A-Za-z0-9_-]*$/.test(n.trim());","tryCatchPattern":null,"preventionTips":["Use slugified names (code-reviewer, not 'code reviewer')","Keep display descriptions inside the TOML, not in the filename","Validate names in config loaders before calling agent APIs"],"tags":["cli","validation","agents","naming-convention"],"backgroundTag":"invalid-identifier","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}