{"record":{"id":"852e40ed88a989fa","repo":"decolua/9router","slug":"data-dir-configured-not-writable-fallback","errorCode":null,"errorMessage":"[DATA_DIR] '${configured}' not writable → fallback ~/.${APP_NAME}","messagePattern":"\\[DATA_DIR\\] '(.+?)' not writable → fallback ~/\\.(.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/lib/dataDir.js","lineNumber":30,"sourceCode":"}\n\nexport function getDataDir() {\n  const configured = process.env.DATA_DIR;\n  if (!configured) return defaultDir();\n\n  // On Windows, ignore Unix-style absolute paths (e.g. /var/lib/...) that come\n  // from a Linux-targeted .env or Docker config — they are not valid here.\n  if (process.platform === \"win32\" && /^\\//.test(configured)) {\n    console.warn(`[DATA_DIR] '${configured}' is a Unix path on Windows → fallback to default`);\n    return defaultDir();\n  }\n\n  try {\n    fs.mkdirSync(configured, { recursive: true });\n    return configured;\n  } catch (e) {\n    if (e?.code === \"EACCES\" || e?.code === \"EPERM\") {\n      console.warn(`[DATA_DIR] '${configured}' not writable → fallback ~/.${APP_NAME}`);\n      return defaultDir();\n    }\n    throw e;\n  }\n}\n\nexport const DATA_DIR = getDataDir();\n","sourceCodeStart":12,"sourceCodeEnd":38,"githubUrl":"https://github.com/decolua/9router/blob/90b52e06ffd666b7929554211474d01588f6b1f8/src/lib/dataDir.js#L12-L38","documentation":"Warning from getDataDir() when the configured DATA_DIR cannot be created or written: fs.mkdirSync throws EACCES or EPERM. The function logs this and falls back to the default ~/.<APP_NAME> directory instead of crashing. Any other error code is rethrown.","triggerScenarios":"DATA_DIR points to a directory the process user cannot create or write: permission-protected path (e.g. /var/lib/... without root, C:\\Program Files\\...), read-only volume, sandboxed/container filesystem, or a parent dir owned by another user.","commonSituations":"Running the app as non-root with DATA_DIR under /var or /etc; Docker container with a read-only mount; systemd service with a hardened (ProtectSystem) unit; Windows service account lacking rights to the target folder.","solutions":["Grant the running user write access: chown/chmod the DATA_DIR path (or icacls on Windows).","Change DATA_DIR to a user-writable location (e.g. ~/.9router/data or /opt/9router/data with correct ownership).","Remove DATA_DIR to accept the default fallback directory.","In Docker, mount a writable volume at DATA_DIR and ensure the container user owns it."],"exampleFix":"// before (docker-compose.yml)\nvolumes: []  # container fs read-only\n// after\nvolumes:\n  - 9router-data:/data\nenvironment:\n  - DATA_DIR=/data","handlingStrategy":"validation","validationCode":"import fs from \"node:fs\";\nconst d = process.env.DATA_DIR;\nif (d) {\n  try { fs.mkdirSync(d, { recursive: true }); fs.accessSync(d, fs.constants.W_OK); }\n  catch (e) { console.warn(`DATA_DIR ${d} not writable (${e.code}) — fix permissions or unset DATA_DIR`); }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check writability of DATA_DIR with the same user that runs the app before launching.","In Docker, mount a writable volume and match ownership to the container user (chown).","Avoid system paths (/var/lib, C:\\Program Files) unless the service account owns them.","Run a preflight check in your start script and fail fast with a clear message."],"tags":["filesystem","permissions","env-var","configuration"],"backgroundTag":"directory-not-writable","analyzedSha":"90b52e06ffd666b7929554211474d01588f6b1f8","analyzedAt":"2026-08-30T21:05:45.952Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}