{"record":{"id":"888a4165eddbbe1f","repo":"bmad-code-org/BMAD-METHOD","slug":"label-is-not-writable-dirpath","errorCode":null,"errorMessage":"${label} is not writable: ${dirPath}","messagePattern":"(.+?) is not writable: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"tools/installer/core/install-paths.js","lineNumber":128,"sourceCode":"    throw new Error(`${label} exists but is not a directory: ${dirPath}`);\n  }\n\n  try {\n    await fs.ensureDir(dirPath);\n  } catch (error) {\n    if (error.code === 'EACCES') {\n      throw new Error(`${label}: permission denied creating directory: ${dirPath}`);\n    }\n    if (error.code === 'ENOSPC') {\n      throw new Error(`${label}: no space left on device: ${dirPath}`);\n    }\n    throw new Error(`${label}: cannot create directory: ${dirPath} (${error.message})`);\n  }\n\n  try {\n    await fs.access(dirPath, fs.constants.R_OK | fs.constants.W_OK);\n  } catch {\n    throw new Error(`${label} is not writable: ${dirPath}`);\n  }\n}\n\nmodule.exports = { InstallPaths };\n","sourceCodeStart":110,"sourceCodeEnd":133,"githubUrl":"https://github.com/bmad-code-org/BMAD-METHOD/blob/b70486b9bdcb0a404d329e2a763b57964e7f1360/tools/installer/core/install-paths.js#L110-L133","documentation":"Thrown by ensureWritableDir after the directory exists (or was just created) but fs.access with R_OK|W_OK fails — the process cannot write to it. Catches the case where the directory is present yet not writable by the current user.","triggerScenarios":"InstallPaths.create() successfully resolves/creates the project root or a _bmad subdirectory, but the final R_OK|W_OK access check fails (e.g. directory owned by another user, read-only mount).","commonSituations":"Directory created by root but installer runs as a normal user, a read-only filesystem mount, ACLs denying write, or a parent that allows mkdir but not subsequent writes.","solutions":["Take ownership / grant write: `chown` or `chmod +w <dirPath>`.","Choose a target the current user fully owns.","If read-only mount, remount read-write or relocate the target."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"await fs.access(dirPath, fs.constants.R_OK | fs.constants.W_OK);","typeGuard":null,"tryCatchPattern":"try {\n  await ensureWritableDir(dirPath, label);\n} catch (error) {\n  if (error.message.includes('is not writable')) { /* fix ownership/perms */ }\n  throw error;\n}","preventionTips":["Ensure the installer runs as the owner of the target directory.","Avoid read-only mounts for install targets."],"tags":["filesystem","permissions","precondition","installer"],"backgroundTag":null,"analyzedSha":"b70486b9bdcb0a404d329e2a763b57964e7f1360","analyzedAt":"2026-08-13T01:21:12.247Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}