Yeachan-Heo/oh-my-codex · warning
[omx] warning: failed to create notify fallback watcher…
Error message
[omx] warning: failed to create notify fallback watcher state directory
What it means
The CLI tried to create the state directory (<omxRoot>/state) needed to track the notify fallback watcher, and mkdir failed (wrapped in .catch so execution continues). The watcher subsystem will be degraded because its PID file cannot be written.
Solutions
- Check permissions of the .omx directory: `ls -la .omx` and `chmod`/`chown` as needed
- Remove any regular file blocking creation of the state directory
- If on a read-only FS, point the omx root/state dir to a writable location via config or env
Example fix
// before mkdir .omx/state # EEXIST: file 'state' // after rm .omx/state && mkdir -p .omx/state
Defensive patterns
Strategy: validation
Validate before calling
import { existsSync, statSync, accessSync, constants } from 'node:fs';
function stateDirWritable(root: string): boolean {
const dir = `${root}/state`;
if (existsSync(dir)) { try { accessSync(dir, constants.W_OK); return statSync(dir).isDirectory(); } catch { return false; } }
try { accessSync(root, constants.W_OK); return true; } catch { return false; }
} Prevention
- Pre-create .omx/state with correct ownership in setup scripts
- Never mix sudo and non-sudo runs
- Keep the project on a writable filesystem
When it happens
Trigger: ensureWatcherSetup path where mkdir(join(omxRoot(cwd),'state'), {recursive:true}) rejects — permission denied, read-only filesystem, or a file exists where the directory should be.
Common situations: Project directory owned by root while running as a normal user; .omx directory made read-only; a file named 'state' already exists in the omx root; read-only container filesystems.
Related errors
- [omx] warning: failed to create hook-derived watcher state…
- failed to persist HUD authority invalid-state diagnostic
- [native-assets] unable to create cache root
- [api] failed to launch native binary: executable is blocked
- autoresearch_candidate_missing
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/8176159cfa7d4ba1.
Report an issue: GitHub.
Appendix: source
Thrown at src/cli/index.ts:7752
async function startNotifyFallbackWatcher(
cwd: string,
options: { codexHomeOverride?: string; enableAuthority?: boolean; sessionId?: string } = {},
): Promise<void> {
const { mkdir, writeFile } = await import("fs/promises");
const pidPath = notifyFallbackPidPath(cwd);
const reapResult = await reapStaleNotifyFallbackWatcher(pidPath);
if (reapResult === "recent_active") return;
if (!shouldEnableNotifyFallbackWatcher(process.env, process.platform)) return;
const pkgRoot = getPackageRoot();
const watcherScript = resolveNotifyFallbackWatcherScript(pkgRoot);
const notifyScript = resolveNotifyHookScript(pkgRoot);
if (!existsSync(watcherScript) || !existsSync(notifyScript)) return;
await mkdir(join(omxRoot(cwd), "state"), { recursive: true }).catch(
(error: unknown) => {
console.warn(
"[omx] warning: failed to create notify fallback watcher state directory",
{
cwd,
error: error instanceof Error ? error.message : String(error),
},
);
},
);
const watcherEnv = buildNotifyFallbackWatcherEnv(process.env, {
codexHomeOverride: options.codexHomeOverride,
omxRootOverride: resolveOmxRootForLaunch(cwd, process.env),
enableAuthority: options.enableAuthority === true,
sessionId: options.sessionId,
});
let watcherPid: number | undefined;
try {
watcherPid = await launchBackgroundHelper(
[View on GitHub (pinned to 3ad79a8a6f)