ruvnet/ruflo · error · Error

Cannot write to project path: ${this.projectPath}

Error message

Cannot write to project path: ${this.projectPath}

What it means

Initializer.validateProjectPath() probes writability by ensuring the directory exists, then creating and deleting a '.codex-init-test' temp file inside it. Any failure — EACCES/EPERM, ENOSPC, ENOTDIR (projectPath is an existing file), read-only mount — is rethrown as 'Cannot write to project path', unfortunately swallowing the original errno.

Source

Thrown at v3/@claude-flow/codex/src/initializer.ts:254

        result.warnings = warnings;
      }
      return result;
    }
  }

  /**
   * Validate that the project path is valid and writable
   */
  private async validateProjectPath(): Promise<void> {
    try {
      await fs.ensureDir(this.projectPath);

      // Check write permissions by attempting to create a temp file
      const tempFile = path.join(this.projectPath, '.codex-init-test');
      await fs.writeFile(tempFile, 'test', 'utf-8');
      await fs.remove(tempFile);
    } catch (error) {
      throw new Error(`Cannot write to project path: ${this.projectPath}`);
    }
  }

  /**
   * Check if project is already initialized
   */
  private async isAlreadyInitialized(): Promise<boolean> {
    const agentsMdExists = await fs.pathExists(path.join(this.projectPath, 'AGENTS.md'));
    const agentsConfigExists = await fs.pathExists(path.join(this.projectPath, '.agents', 'config.toml'));
    return agentsMdExists || agentsConfigExists;
  }

  /**
   * Check if we should write a file (force mode or doesn't exist)
   */
  private async shouldWriteFile(filePath: string): Promise<boolean> {
    if (this.force) {
      return true;

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Check ownership/permissions: `ls -ld <path>` and `id`; chown/chmod so your user can write (e.g. `sudo chown -R $(whoami) <path>`)
  2. Pick a writable location (home dir) or remount/adjust the container volume as writable
  3. If the path is an existing file, remove it or choose a real directory; free disk space if ENOSPC
  4. Reproduce the root cause manually: `touch <path>/.codex-init-test && rm <path>/.codex-init-test` to see the OS error

Example fix

# diagnose the real OS error the wrapper hides
touch /path/to/project/.codex-init-test
# fix ownership
sudo chown -R "$USER" /path/to/project
Defensive patterns

Strategy: validation

Validate before calling

import { accessSync, constants, statSync } from 'node:fs';
function canWriteProject(p: string): boolean {
  statSync(p).isDirectory();
  accessSync(p, constants.W_OK | constants.X_OK);
  const probe = path.join(p, '.codex-init-test');
  writeFileSync(probe, ''); unlinkSync(probe);
  return true;
}

Try / catch

try { await initializer.run(); } catch (e) { if (/Cannot write to project path/.test(String(e))) { fs.accessSync(dir, fs.constants.W_OK); /* surfaces the real errno */ } throw e; }

Prevention

When it happens

Trigger: Running init against a directory you cannot write (root-owned, restricted mount), a full disk, a path that is actually a regular file, or a corporate-locked home directory; sandboxed runners with read-only project mounts.

Common situations: `sudo`-created project dirs later used as a normal user; Docker/CI mounts of the project read-only; deploying into /opt or other root-owned locations; devcontainers with permission mismatches.

Related errors


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/5caec4416fd2673d. Report an issue: GitHub.