{"record":{"id":"91e2f610da94e283","repo":"nexu-io/open-design","slug":"od-data-dir-resolved-is-not-writable-e-mes","errorCode":null,"errorMessage":"OD_DATA_DIR \"${resolved}\" is not writable: ${e.message} Current user: ${currentUser} Check whether the folder or one of its parents is owned by another user, is a symlink to a protected location, or was previously created with sudo. Try: ls -ld \"${parentDir}\" \"${resolved}\" If the folder should belong to you, fix ownership/permissions, for example: sudo chown -R \"${currentUser}\":staff \"${parentDir}\" && chmod -R u+rwX \"${parentDir}\"","messagePattern":"OD_DATA_DIR \"(.+?)\" is not writable: (.+?) Current user: (.+?) Check whether the folder or one of its parents is owned by another user, is a symlink to a protected location, or was previously created with sudo\\. Try: ls -ld \"(.+?)\" \"(.+?)\" If the folder should belong to you, fix ownership/permissions, for example: sudo chown -R \"(.+?)\":staff \"(.+?)\" && chmod -R u\\+rwX \"(.+?)\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"apps/daemon/src/daemon-paths.ts","lineNumber":152,"sourceCode":"    }\n    return path.join(projectRoot, '.od');\n  }\n\n  const resolved = resolveProjectRelativePath(value, projectRoot);\n  try {\n    fs.mkdirSync(resolved, { recursive: true });\n    fs.accessSync(resolved, fs.constants.W_OK);\n  } catch (err) {\n    const e = err as Error;\n    const currentUser = (() => {\n      try {\n        return os.userInfo().username;\n      } catch {\n        return process.env.USER ?? process.env.LOGNAME ?? 'unknown';\n      }\n    })();\n    const parentDir = path.dirname(resolved);\n    throw new Error(\n      [\n        `OD_DATA_DIR \"${resolved}\" is not writable: ${e.message}`,\n        `Current user: ${currentUser}`,\n        'Check whether the folder or one of its parents is owned by another user, is a symlink to a protected location, or was previously created with sudo.',\n        `Try: ls -ld \"${parentDir}\" \"${resolved}\"`,\n        `If the folder should belong to you, fix ownership/permissions, for example: sudo chown -R \"${currentUser}\":staff \"${parentDir}\" && chmod -R u+rwX \"${parentDir}\"`,\n      ].join(' '),\n    );\n  }\n  return resolved;\n}\n","sourceCodeStart":134,"sourceCodeEnd":164,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/apps/daemon/src/daemon-paths.ts#L134-L164","documentation":"Thrown by resolveDataDir() when the resolved OD_DATA_DIR cannot be created (mkdirSync recursive) or is not writable (accessSync W_OK). The message is intentionally verbose: it includes the underlying fs error, the current OS user, the parent dir, and concrete remediation commands (ls -ld, chown, chmod). It exists so permission/symlink/sudo-ownership problems surface with actionable diagnostics rather than a cryptic EACCES.","triggerScenarios":"OD_DATA_DIR points at a directory owned by another user (commonly root, after a sudo run), a read-only mount, a symlink to a protected location, or a path whose parent lacks write permission.","commonSituations":"User previously ran the daemon with sudo, leaving dirs root-owned; OD_DATA_DIR on a read-only filesystem or a Docker volume mounted read-only; a symlink chain lands in /usr/local or another system path; SELinux/AppArmor denies writes despite Unix perms looking fine.","solutions":["Run the chown/chmod command suggested in the error message for the parent dir and target (e.g. sudo chown -R $USER:staff <parent> && chmod -R u+rwX <parent>).","Point OD_DATA_DIR at a directory the current user owns and that is not a symlink to a protected location.","If the dir is on a mounted volume, remount it read-write or pick a writable mount."],"exampleFix":"# before: dir left root-owned by a prior sudo run\nls -ld /var/lib/open-design   # owner: root\n\n# after: fix ownership, then restart the daemon\nsudo chown -R $(whoami):staff /var/lib/open-design\nchmod -R u+rwX /var/lib/open-design","handlingStrategy":"validation","validationCode":"import fs from 'node:fs';\nconst target = resolveProjectRelativePath(process.env.OD_DATA_DIR!, projectRoot);\nfs.mkdirSync(target, { recursive: true });\ntry { fs.accessSync(target, fs.constants.W_OK); }\ncatch { throw new Error(`OD_DATA_DIR ${target} not writable by ${os.userInfo().username}`); }","typeGuard":"function isWritable(p: string): boolean {\n  try { fs.accessSync(p, fs.constants.W_OK); return true; } catch { return false; }\n}","tryCatchPattern":"try { resolveDataDir(process.env.OD_DATA_DIR, projectRoot); }\ncatch (e) {\n  if (e instanceof Error && /not writable/.test(e.message)) {\n    // surface the embedded chown/chmod hint; do not auto-fix permissions\n  } else throw e;\n}","preventionTips":["Never run the daemon with sudo — it leaves dirs root-owned.","Provision OD_DATA_DIR on a writable volume owned by the daemon user.","Add a startup ownership check in the launcher and fail fast with the same hint."],"tags":["daemon","paths","permissions","filesystem","boot"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}