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

editor exited with status ${result.status ?? 'unknown'}

Error message

editor exited with status ${result.status ?? 'unknown'}

What it means

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.

Source

Thrown at src/cli/agents.ts:223

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

async function editNativeAgent(
  name: string,
  options: { cwd?: string; scope?: AgentScope; editor?: string } = {},
): Promise<string> {
  const path = resolveExistingAgentPath(name, options);
  const editor = options.editor ?? process.env.EDITOR ?? process.env.VISUAL ?? 'vi';
  const result = spawnSync(editor, [path], {
    stdio: 'inherit',
    shell: true,
    env: process.env,
  });
  if (result.status !== 0) {
    throw new Error(`editor exited with status ${result.status ?? 'unknown'}`);
  }
  return path;
}

async function removeNativeAgent(
  name: string,
  options: { cwd?: string; scope?: AgentScope; force?: boolean } = {},
): Promise<string> {
  ensureInteractiveRemove(Boolean(options.force));
  const path = resolveExistingAgentPath(name, options);
  if (!options.force) {
    const confirmed = await confirmRemove(path);
    if (!confirmed) {
      throw new Error('remove aborted by user (pass --force to skip confirmation)');
    }
  }
  await rm(path, { force: true });
  return path;

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Verify $EDITOR is installed and on PATH (echo $EDITOR; command -v $EDITOR)
  2. Exit the editor cleanly (avoid :cq in vim)
  3. Set EDITOR to a simple binary name or valid shell command string

Example fix

# before
EDITOR=nonexistent-edi omx agent edit reviewer

# after
export EDITOR=vim
omx agent edit reviewer
Defensive patterns

Strategy: validation

Validate before calling

import { commandExistsSync } from 'command-exists';
const editor = process.env.EDITOR ?? 'vi';
if (!commandExistsSync(editor.split(' ')[0])) {
  console.error(`editor not found: ${editor}`);
  process.exit(2);
}

Try / catch

try {
  await editNativeAgent(name);
} catch (e) {
  if (e instanceof Error && /editor exited with status/.test(e.message)) {
    // fall back to printing the path so the user can edit manually
    console.log(`edit manually: ${agentPath}`);
  } else throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: EDITOR unset and no sane default, EDITOR='code --wait' quirks, exiting vim with an error code, or containers without editors installed.

Related errors


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