affaan-m/ECC · error · Error

Refusing to create non-regular legacy sync path: ${filePath}

Error message

Refusing to create non-regular legacy sync path: ${filePath}

What it means

createRegularFileNoFollow creates the state file with O_WRONLY|O_CREAT|O_EXCL|O_NOFOLLOW and then requires fstat on the fresh descriptor to report a regular file. O_EXCL guarantees the path did not exist before, so reaching a non-regular stat means the filesystem handed back something unexpected — an exotic/FUSE mount that does not behave like a normal directory tree, or the just-created entry being swapped for a special file in the same instant.

Source

Thrown at scripts/lib/codex-legacy-sync.js:95

  }
}

function replaceOpenedRegularFile(opened, content, mode = null) {
  const buffer = Buffer.isBuffer(content) ? content : Buffer.from(content);
  fs.ftruncateSync(opened.descriptor, 0);
  fs.writeSync(opened.descriptor, buffer, 0, buffer.length, 0);
  if (mode) fs.fchmodSync(opened.descriptor, mode);
  fs.fsyncSync(opened.descriptor);
}

function createRegularFileNoFollow(filePath, content, mode = 0o600) {
  const noFollow = fs.constants.O_NOFOLLOW || 0;
  const flags = fs.constants.O_WRONLY | fs.constants.O_CREAT | fs.constants.O_EXCL | noFollow;
  const descriptor = fs.openSync(filePath, flags, mode);
  try {
    const stat = fs.fstatSync(descriptor);
    if (!stat.isFile()) {
      throw new Error(`Refusing to create non-regular legacy sync path: ${filePath}`);
    }
    fs.writeFileSync(descriptor, content);
    fs.fchmodSync(descriptor, mode);
    fs.fsyncSync(descriptor);
  } finally {
    fs.closeSync(descriptor);
  }
}

function removeOpenedRegularFile(filePath, opened) {
  const quarantineDir = fs.mkdtempSync(path.join(path.dirname(filePath), '.ecc-remove-'));
  const quarantinePath = path.join(quarantineDir, path.basename(filePath));
  fs.renameSync(filePath, quarantinePath);
  const quarantined = openRegularFileNoFollow(quarantinePath);
  const openedStat = fs.fstatSync(opened.descriptor, { bigint: true });
  const quarantinedStat = fs.fstatSync(quarantined.descriptor, { bigint: true });
  fs.closeSync(quarantined.descriptor);
  fs.closeSync(opened.descriptor);

View on GitHub (pinned to 06c5e118c4)

Solutions

  1. Move the state directory onto a local POSIX filesystem (ext4/APFS/NTFS) and retry.
  2. If the directory must be synced, exclude the live state file and sync copies instead.
  3. Re-run after remounting the odd filesystem — if it persists, report the mount type as a bug against codex-legacy-sync.

Example fix

# before: HOME on a FUSE cloud mount
$ df -T ~/.codex
~/.codex  fuseblk ...

# after
$ export CODEX_HOME="$HOME/.codex-local"   # local fs
$ ecc codex sync
Defensive patterns

Strategy: retry

Validate before calling

import fs from 'node:fs';
function assertPosixCreateDir(dir) {
  const probe = path.join(dir, `.probe-${process.pid}`);
  const fd = fs.openSync(probe, fs.constants.O_WRONLY | fs.constants.O_CREAT | fs.constants.O_EXCL, 0o600);
  try { if (!fs.fstatSync(fd).isFile()) throw new Error(`${dir} does not behave like a POSIX dir`); }
  finally { fs.closeSync(fd); fs.unlinkSync(probe); }
}

Try / catch

try { createAndSync(); } catch (e) {
  if (/Refusing to create non-regular/.test(e.message)) { throw new Error('move the state dir off FUSE/network mounts and retry'); }
  throw e;
}

Prevention

When it happens

Trigger: The Codex state directory lives on a FUSE/network/virtual filesystem whose O_EXCL creates resolve oddly; a race replaces the newly created file with a FIFO/socket before fstat.

Common situations: HOME or the config dir redirected onto a cloud-sync FUSE mount (Dropbox, gdrive-fs), a network share, or a container virtual filesystem; rare hostile races.

Related errors


AI-assisted analysis of affaan-m/ECC@06c5e118c4 (2026-08-18). Data as JSON: /api/errors/516d220a514c579c. Report an issue: GitHub.