Yeachan-Heo/oh-my-codex · warning
[omx] warning: failed to stop stale hook-derived watcher
Error message
[omx] warning: failed to stop stale hook-derived watcher
What it means
Same as the notify-fallback variant but for the hook-derived watcher: the CLI found a previous watcher PID file and process.kill(prev.pid, 'SIGTERM') threw (e.g. EPERM or invalid PID). The old watcher may keep running alongside a new one.
Source
Thrown at src/cli/index.ts:7838
async function startHookDerivedWatcher(cwd: string): Promise<void> {
if (process.env.OMX_HOOK_DERIVED_SIGNALS !== "1") return;
const { mkdir, writeFile, readFile } = await import("fs/promises");
const pidPath = hookDerivedWatcherPidPath(cwd);
const pkgRoot = getPackageRoot();
const watcherScript = resolveHookDerivedWatcherScript(pkgRoot);
if (!existsSync(watcherScript)) return;
if (existsSync(pidPath)) {
try {
const prev = JSON.parse(await readFile(pidPath, "utf-8")) as {
pid?: number;
};
if (prev && typeof prev.pid === "number") {
process.kill(prev.pid, "SIGTERM");
}
} catch (error: unknown) {
console.warn("[omx] warning: failed to stop stale hook-derived watcher", {
path: pidPath,
error: error instanceof Error ? error.message : String(error),
});
}
}
await mkdir(join(omxRoot(cwd), "state"), { recursive: true }).catch(
(error: unknown) => {
console.warn(
"[omx] warning: failed to create hook-derived watcher state directory",
{
cwd,
error: error instanceof Error ? error.message : String(error),
},
);
},
);
let watcherPid: number | undefined;View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Manually kill the stale watcher: `kill $(cat .omx/state/hook-derived-watcher.pid)` or pkill the script name
- Remove the stale PID file
- Run subsequent omx commands as the user that owns the state directory
Example fix
// before # EPERM killing old watcher # after sudo kill $(cat .omx/state/hook-derived-watcher.pid); rm .omx/state/hook-derived-watcher.pid
Defensive patterns
Strategy: try-catch
Validate before calling
function parsePid(raw: string): number | undefined {
const n = Number(raw);
return Number.isInteger(n) && n > 1 ? n : undefined;
} Try / catch
try { process.kill(prev.pid,'SIGTERM'); } catch (e: any) { if (e?.code !== 'ESRCH') console.warn(...); } Prevention
- Sanitize pid files before killing
- Use one user for all omx operations
- Clean state after hard crashes
When it happens
Trigger: Stopping a stale hook-derived watcher whose recorded PID belongs to another user (EPERM) or no longer maps to a valid signal target in a way that throws a non-ESRCH error.
Common situations: User switching on a shared checkout; PID files left from a crashed session; containers with PID namespaces remapped.
Related errors
- [omx] warning: failed to stop stale notify fallback watcher
- [omx] warning: failed to stop hook-derived watcher process
- [omx] warning: failed to create hook-derived watcher state d
- [omx] warning: failed to launch hook-derived watcher
- [omx] warning: failed to write hook-derived watcher pid file
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/c0bde09e321678f4.
Report an issue: GitHub.