{"record":{"id":"1ce1c6f3a592e719","repo":"Yeachan-Heo/oh-my-codex","slug":"editor-exited-with-status-result-status-unkn","errorCode":null,"errorMessage":"editor exited with status ${result.status ?? 'unknown'}","messagePattern":"editor exited with status (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/cli/agents.ts","lineNumber":223,"sourceCode":"function ensureInteractiveRemove(force: boolean): void {\n  if (force) return;\n  if (process.stdin.isTTY && process.stdout.isTTY) return;\n  throw new Error('remove requires an interactive terminal; rerun with --force in non-interactive environments');\n}\n\nasync function editNativeAgent(\n  name: string,\n  options: { cwd?: string; scope?: AgentScope; editor?: string } = {},\n): Promise<string> {\n  const path = resolveExistingAgentPath(name, options);\n  const editor = options.editor ?? process.env.EDITOR ?? process.env.VISUAL ?? 'vi';\n  const result = spawnSync(editor, [path], {\n    stdio: 'inherit',\n    shell: true,\n    env: process.env,\n  });\n  if (result.status !== 0) {\n    throw new Error(`editor exited with status ${result.status ?? 'unknown'}`);\n  }\n  return path;\n}\n\nasync function removeNativeAgent(\n  name: string,\n  options: { cwd?: string; scope?: AgentScope; force?: boolean } = {},\n): Promise<string> {\n  ensureInteractiveRemove(Boolean(options.force));\n  const path = resolveExistingAgentPath(name, options);\n  if (!options.force) {\n    const confirmed = await confirmRemove(path);\n    if (!confirmed) {\n      throw new Error('remove aborted by user (pass --force to skip confirmation)');\n    }\n  }\n  await rm(path, { force: true });\n  return path;","sourceCodeStart":205,"sourceCodeEnd":241,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/cli/agents.ts#L205-L241","documentation":"editNativeAgent spawns $EDITOR (spawnSync with shell) on the agent TOML and requires exit status 0. A non-zero, null (killed by signal), or unknown status produces this error. The editor is expected to be found via PATH and env is inherited.","triggerScenarios":"EDITOR set to a non-existent binary, editor exiting non-zero (vim :cq), editor killed by a signal, or EDITOR containing arguments that the shell mangles.","commonSituations":"EDITOR unset and no sane default, EDITOR='code --wait' quirks, exiting vim with an error code, or containers without editors installed.","solutions":["Verify $EDITOR is installed and on PATH (echo $EDITOR; command -v $EDITOR)","Exit the editor cleanly (avoid :cq in vim)","Set EDITOR to a simple binary name or valid shell command string"],"exampleFix":"# before\nEDITOR=nonexistent-edi omx agent edit reviewer\n\n# after\nexport EDITOR=vim\nomx agent edit reviewer","handlingStrategy":"validation","validationCode":"import { commandExistsSync } from 'command-exists';\nconst editor = process.env.EDITOR ?? 'vi';\nif (!commandExistsSync(editor.split(' ')[0])) {\n  console.error(`editor not found: ${editor}`);\n  process.exit(2);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await editNativeAgent(name);\n} catch (e) {\n  if (e instanceof Error && /editor exited with status/.test(e.message)) {\n    // fall back to printing the path so the user can edit manually\n    console.log(`edit manually: ${agentPath}`);\n  } else throw e;\n}","preventionTips":["Set EDITOR to an installed binary in ~/.bashrc / CI env","Exit editors cleanly (avoid vim's :cq)","Prefer non-interactive flows (write the TOML programmatically) in automation"],"tags":["cli","agents","editor","subprocess","environment"],"backgroundTag":"editor-launch-failed","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}