Yeachan-Heo/oh-my-codex · warning

[omx] warning: failed to stop hook-derived watcher process

Error message

[omx] warning: failed to stop hook-derived watcher process

What it means

Stopping the hook-derived watcher failed: either the pid file could not be read/parsed or process.kill(parsed.pid,'SIGTERM') threw. The watcher likely keeps running in the background.

Source

Thrown at src/cli/index.ts:7936

      },
    );
  });
}

async function stopHookDerivedWatcher(cwd: string): Promise<void> {
  const { readFile, unlink } = await import("fs/promises");
  const pidPath = hookDerivedWatcherPidPath(cwd);
  if (!existsSync(pidPath)) return;

  try {
    const parsed = JSON.parse(await readFile(pidPath, "utf-8")) as {
      pid?: number;
    };
    if (parsed && typeof parsed.pid === "number") {
      process.kill(parsed.pid, "SIGTERM");
    }
  } catch (error: unknown) {
    console.warn("[omx] warning: failed to stop hook-derived watcher process", {
      path: pidPath,
      error: error instanceof Error ? error.message : String(error),
    });
  }

  await unlink(pidPath).catch((error: unknown) => {
    console.warn(
      "[omx] warning: failed to remove hook-derived watcher pid file",
      {
        path: pidPath,
        error: error instanceof Error ? error.message : String(error),
      },
    );
  });
}

async function flushNotifyFallbackOnce(
  cwd: string,

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Kill the watcher manually: `pkill -f hook-derived-watcher`
  2. Delete the stale pid file under .omx/state
  3. Serialize teardown operations per project

Example fix

// before
# warning: failed to stop hook-derived watcher process

# after
pkill -f hook-derived-watcher; rm -f .omx/state/hook-derived-watcher.pid
Defensive patterns

Strategy: try-catch

Validate before calling

function validWatcherRecord(raw: string): { pid: number } | null {
  try { const p = JSON.parse(raw); return typeof p?.pid === 'number' && Number.isInteger(p.pid) ? p : null; } catch { return null; }
}

Try / catch

try { if (parsed?.pid) process.kill(parsed.pid,'SIGTERM'); } catch (e: any) { if (e?.code !== 'ESRCH') console.warn('[omx] warning: failed to stop hook-derived watcher process', { error: e }); }

Prevention

When it happens

Trigger: readFile or process.kill throws (ENOENT on a concurrently-removed file, EPERM, EINVAL from a bad PID) in the stop-hook-derived-watcher path.

Common situations: Concurrent omx teardown racing on the same pid file; watcher started by a different user; PID file with non-numeric pid field.

Related errors


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