Yeachan-Heo/oh-my-codex · warning

[omx] warning: failed to create notify fallback watcher stat

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.

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)

Solutions

  1. Check permissions of the .omx directory: `ls -la .omx` and `chmod`/`chown` as needed
  2. Remove any regular file blocking creation of the state directory
  3. 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

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


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