nexu-io/open-design · critical · Error
OD_DATA_DIR "${resolved}" is not writable: ${e.message} Curr
Error message
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}" What it means
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.
Source
Thrown at apps/daemon/src/daemon-paths.ts:152
}
return path.join(projectRoot, '.od');
}
const resolved = resolveProjectRelativePath(value, projectRoot);
try {
fs.mkdirSync(resolved, { recursive: true });
fs.accessSync(resolved, fs.constants.W_OK);
} catch (err) {
const e = err as Error;
const currentUser = (() => {
try {
return os.userInfo().username;
} catch {
return process.env.USER ?? process.env.LOGNAME ?? 'unknown';
}
})();
const parentDir = path.dirname(resolved);
throw new Error(
[
`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}"`,
].join(' '),
);
}
return resolved;
}
View on GitHub (pinned to 5be4028344)
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.
Example fix
# before: dir left root-owned by a prior sudo run ls -ld /var/lib/open-design # owner: root # after: fix ownership, then restart the daemon sudo chown -R $(whoami):staff /var/lib/open-design chmod -R u+rwX /var/lib/open-design
Defensive patterns
Strategy: validation
Validate before calling
import fs from 'node:fs';
const target = resolveProjectRelativePath(process.env.OD_DATA_DIR!, projectRoot);
fs.mkdirSync(target, { recursive: true });
try { fs.accessSync(target, fs.constants.W_OK); }
catch { throw new Error(`OD_DATA_DIR ${target} not writable by ${os.userInfo().username}`); } Type guard
function isWritable(p: string): boolean {
try { fs.accessSync(p, fs.constants.W_OK); return true; } catch { return false; }
} Try / catch
try { resolveDataDir(process.env.OD_DATA_DIR, projectRoot); }
catch (e) {
if (e instanceof Error && /not writable/.test(e.message)) {
// surface the embedded chown/chmod hint; do not auto-fix permissions
} else throw e;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- OD_DATA_DIR is required when OD_SANDBOX_MODE is enabled
- ${RESOURCE_ROOT_ENV} must be under the workspace root or app
- ARTIFACT_MANIFEST_INVALID
- ARTIFACT_MANIFEST_REQUIRED
- ARTIFACT_PUBLICATION_BLOCKED
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/91e2f610da94e283.
Report an issue: GitHub.