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
- Check ownership/permissions: `ls -ld <path>` and `id`; chown/chmod so your user can write (e.g. `sudo chown -R $(whoami) <path>`)
- Pick a writable location (home dir) or remount/adjust the container volume as writable
- If the path is an existing file, remove it or choose a real directory; free disk space if ENOSPC
- 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
- Pre-flight writability yourself so the OS error (EACCES vs ENOSPC vs ENOTDIR) is visible
- Verify the target is a directory you own before init
- Keep project dirs out of root-owned or read-only locations
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
- Failed to initialize @ruvector/ruvllm-wasm: ${err}
- hexToBytes: odd-length hex string
- MCP initialization failed: ${initResponse.error.message}
- trajectory envelope not found: ${path}
- String length ${len} exceeds remaining buffer
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/5caec4416fd2673d.
Report an issue: GitHub.