{"record":{"id":"f726df64c484c1f9","repo":"can1357/oh-my-pi","slug":"project-directory-is-not-accessible-cwd","errorCode":null,"errorMessage":"Project directory is not accessible: ${cwd}","messagePattern":"Project directory is not accessible: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/blob-broker/uploaders.ts","lineNumber":98,"sourceCode":"export function createCommandUploader(template: string): BlobUploader {\n\tconst argvTemplate = splitCommandTemplate(template);\n\tif (argvTemplate.length === 0) throw new Error(\"images.urls.command is empty\");\n\tif (!argvTemplate.some(arg => arg.includes(\"{file}\"))) {\n\t\tthrow new Error(\"images.urls.command must reference {file}\");\n\t}\n\treturn {\n\t\tdestination: \"command\",\n\t\tasync upload(request: BlobUploadRequest): Promise<BlobPublication> {\n\t\t\tconst { bytes, mimeType, extension } = request;\n\t\t\tconst file = path.join(os.tmpdir(), `omp-blob-upload-${crypto.randomUUID()}.${extension}`);\n\t\t\tawait Bun.write(file, bytes);\n\t\t\ttry {\n\t\t\t\tconst argv = argvTemplate.map(arg =>\n\t\t\t\t\targ.replaceAll(\"{file}\", file).replaceAll(\"{mime}\", mimeType).replaceAll(\"{ext}\", extension),\n\t\t\t\t);\n\t\t\t\tconst cwd = getProjectDir();\n\t\t\t\tif (!directoryIsEnterableSync(cwd)) {\n\t\t\t\t\tthrow new Error(`Project directory is not accessible: ${cwd}`);\n\t\t\t\t}\n\t\t\t\tconst proc = Bun.spawn(argv, { stdin: \"ignore\", stdout: \"pipe\", stderr: \"pipe\", cwd });\n\t\t\t\tconst timeout = setTimeout(() => proc.kill(), UPLOAD_TIMEOUT_MS);\n\t\t\t\tconst [stdout, stderr, exitCode] = await Promise.all([\n\t\t\t\t\tnew Response(proc.stdout as ReadableStream<Uint8Array>).text(),\n\t\t\t\t\tnew Response(proc.stderr as ReadableStream<Uint8Array>).text(),\n\t\t\t\t\tproc.exited,\n\t\t\t\t]);\n\t\t\t\tclearTimeout(timeout);\n\t\t\t\tif (exitCode !== 0) {\n\t\t\t\t\tthrow new Error(`${argv[0]} exited with code ${exitCode}: ${stderr.trim().slice(-300)}`);\n\t\t\t\t}\n\t\t\t\tconst url = extractUploadUrl(stdout);\n\t\t\t\tif (!url) throw new Error(`${argv[0]} printed no URL on stdout`);\n\t\t\t\treturn { url, destination: \"command\", bytes: bytes.byteLength };\n\t\t\t} finally {\n\t\t\t\tawait fs.rm(file, { force: true });\n\t\t\t}","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/blob-broker/uploaders.ts#L80-L116","documentation":"Before spawning the configured upload command, upload() verifies that the current project directory is enterable (directoryIsEnterableSync) and spawns the process with that directory as cwd. If the directory cannot be entered (missing or lacking permissions) it throws this error rather than spawning the child in an invalid working directory.","triggerScenarios":"Calling upload() when the process's project directory has been deleted or renamed after startup; the cwd was removed by a cleanup task; the process lacks read/search permission on the directory (e.g. running as a different user or in a sandbox); NFS/network mount went offline.","commonSituations":"Running the agent inside a container where the mount was unmounted; deleting the project folder while a session is live; permission tightening (chmod 000) on the working directory; macOS/CI temp-dir cleanup removing the cwd.","solutions":["Restore the project directory or restart the session from an existing directory","Fix directory permissions (chmod/chown so the process user can traverse it)","Re-mount the volume if the directory lives on an unmounted mount","Check you are not running the process from a directory deleted after launch"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"import { directoryIsEnterableSync } from \"...\";\nconst cwd = getProjectDir();\nif (!directoryIsEnterableSync(cwd)) {\n\t// restore cwd, fix permissions, or fail before attempting uploads\n}","typeGuard":null,"tryCatchPattern":"try {\n\tawait uploader.upload(req);\n} catch (err) {\n\tif (err instanceof Error && err.message.startsWith(\"Project directory is not accessible\")) {\n\t\t// verify project dir exists and is traversable by the process user\n\t}\n\tthrow err;\n}","preventionTips":["Don't delete or rename the project directory while a session is running","Ensure the process user has r/x permissions on the project directory","In containers, verify mounts stay attached for the session lifetime","Restart the session from a valid directory after moving the project"],"tags":["filesystem","permissions","working-directory"],"backgroundTag":"cwd-not-accessible","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}