{"record":{"id":"417e227976a731ad","repo":"affaan-m/ECC","slug":"failed-to-create-directory-dirpath-err-mes","errorCode":null,"errorMessage":"Failed to create directory '${dirPath}': ${err.message}","messagePattern":"Failed to create directory '(.+?)': (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/lib/utils.js","lineNumber":102,"sourceCode":"function getTempDir() {\n  return os.tmpdir();\n}\n\n/**\n * Ensure a directory exists (create if not)\n * @param {string} dirPath - Directory path to create\n * @returns {string} The directory path\n * @throws {Error} If directory cannot be created (e.g., permission denied)\n */\nfunction ensureDir(dirPath) {\n  try {\n    if (!fs.existsSync(dirPath)) {\n      fs.mkdirSync(dirPath, { recursive: true });\n    }\n  } catch (err) {\n    // EEXIST is fine (race condition with another process creating it)\n    if (err.code !== 'EEXIST') {\n      throw new Error(`Failed to create directory '${dirPath}': ${err.message}`);\n    }\n  }\n  return dirPath;\n}\n\n/**\n * Get current date in YYYY-MM-DD format\n */\nfunction getDateString() {\n  const now = new Date();\n  const year = now.getFullYear();\n  const month = String(now.getMonth() + 1).padStart(2, '0');\n  const day = String(now.getDate()).padStart(2, '0');\n  return `${year}-${month}-${day}`;\n}\n\n/**\n * Get current time in HH:MM format","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/lib/utils.js#L84-L120","documentation":"ensureDir wraps fs.mkdirSync({recursive:true}) and re-throws any error whose code is not EEXIST (EEXIST is tolerated as a benign race). It fires for permission, disk-space, read-only-filesystem, path-too-long, and quota errors coming from the OS. The thrown message interpolates dirPath and the underlying err.message so the caller can see both the target and the OS reason.","triggerScenarios":"Calling ensureDir on a path under a directory the process has no write permission to (EACCES). Target on a read-only mount (EROFS). Disk full or inode quota exhausted (ENOSPC). Path longer than PATH_MAX (ENAMETOOLONG). A file (not directory) already exists at dirPath (ENOTDIR/EEXIST-on-file — though EEXIST is swallowed, ENOTDIR on a parent is not).","commonSituations":"Running the CLI as a different user than owns the project dir. Docker/container with a read-only volume mount. CI runner out of disk. Symlink loop in the target path. NFS/Homebrew prefixes with restricted permissions on macOS.","solutions":["Check write permission on the parent: `ls -ld <parent>` and `test -w <parent>`; chmod/chown or rerun as the owner.","Free disk/inodes: `df -h <dirPath>` and `df -i <dirPath>`; clear space if full.","Confirm the path is on a writable filesystem (not a read-only mount) and that no regular file occupies dirPath.","Shorten or sanitize dirPath if it is abnormally long, or move the workspace under a shallower root."],"exampleFix":"// before\nensureDir('/opt/ecc/state');  // EACCES if /opt is root-owned\n\n// after — write under a user-owned path and surface mkdir errors with their code\nfunction ensureDirSafe(dirPath) {\n  try {\n    fs.mkdirSync(dirPath, { recursive: true });\n  } catch (err) {\n    if (err.code !== 'EEXIST') {\n      throw new Error(`Failed to create directory '${dirPath}' (${err.code}): ${err.message}`);\n    }\n  }\n  return dirPath;\n}\nensureDirSafe(path.join(os.homedir(), '.local', 'ecc', 'state'));","handlingStrategy":"try-catch","validationCode":"// Pre-flight: parent must exist and be writable; path must not be a regular file.\nconst fs = require('fs');\nconst path = require('path');\nfunction canCreateDir(dirPath) {\n  const parent = path.dirname(path.resolve(dirPath));\n  try {\n    fs.accessSync(parent, fs.constants.W_OK);\n  } catch {\n    return false;\n  }\n  try {\n    const st = fs.statSync(dirPath);\n    return st.isDirectory(); // exists as dir is fine; exists as file is not\n  } catch { return true; } // nothing there yet\n}\nif (!canCreateDir(target)) throw new Error(`Cannot create ${target}: parent not writable or target is a file.`);","typeGuard":null,"tryCatchPattern":"try {\n  ensureDir(target);\n} catch (err) {\n  if (/Failed to create directory/.test(err.message)) {\n    // Retry once on a user-owned fallback, or surface a friendlier message.\n    const fallback = path.join(os.homedir(), '.cache', 'ecc');\n    if (fallback !== target) { ensureDir(fallback); return fallback; }\n  }\n  throw err;\n}","preventionTips":["Run the CLI as the user that owns the target directory.","Avoid read-only mounts for writable state; verify with `mount | grep <path>`.","Monitor disk/inode usage in CI before writing.","Sanitize/normalize long paths before ensureDir to avoid ENAMETOOLONG."],"tags":["filesystem","permissions","node","io"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}