{"record":{"id":"30b8f5ff9a4c1247","repo":"yarnpkg/yarn","slug":"nopermission","errorCode":null,"errorMessage":"noPermission","messagePattern":"noPermission","errorType":"exception","errorClass":"MessageError","httpStatus":null,"severity":"error","filePath":"src/cli/commands/global.js","lineNumber":132,"sourceCode":"\n    return FALLBACK_GLOBAL_PREFIX;\n  }\n\n  return prefix;\n}\n\nexport async function getBinFolder(config: Config, flags: Object): Promise<string> {\n  const prefix = await getGlobalPrefix(config, flags);\n  return path.resolve(prefix, 'bin');\n}\n\nasync function initUpdateBins(config: Config, reporter: Reporter, flags: Object): Promise<() => Promise<void>> {\n  const beforeBins = await getBins(config);\n  const binFolder = await getBinFolder(config, flags);\n\n  function throwPermError(err: Error & {[code: string]: string}, dest: string) {\n    if (err.code === 'EACCES') {\n      throw new MessageError(reporter.lang('noPermission', dest));\n    } else {\n      throw err;\n    }\n  }\n\n  return async function(): Promise<void> {\n    try {\n      await fs.mkdirp(binFolder);\n    } catch (err) {\n      throwPermError(err, binFolder);\n    }\n\n    const afterBins = await getBins(config);\n\n    // remove old bins\n    for (const src of beforeBins) {\n      if (afterBins.has(src)) {\n        // not old","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/yarnpkg/yarn/blob/c2dda503f3759b5be5f0e24ecd9cf5c97a540147/src/cli/commands/global.js#L114-L150","documentation":"During global install/update, `initUpdateBins` creates the global `bin` folder and links binaries. `throwPermError` (`global.js:132`) inspects caught filesystem errors and, when `err.code === 'EACCES'`, rethrows `noPermission` with the failing path. EACCES means the OS denied create/write to that path.","triggerScenarios":"An `EACCES` filesystem error on the global prefix or bin folder — typically `fs.mkdirp(binFolder)` or a subsequent symlink/write fails because the directory is owned by root/another user.","commonSituations":"Default global prefix resolves to `/usr/local/bin` (system-owned); the user ran without sudo but the dir is not writable; previous `sudo yarn global add` changed ownership of `~/.config`/`~/.local`.","solutions":["Reconfigure the global prefix to a user-writable dir: `yarn config set prefix ~/.yarn-global`.","Fix ownership: `sudo chown -R $(whoami) <prefix>`.","Avoid `sudo yarn global add` (it root-owns files and worsens the problem).","Use a node version manager (nvm) so the prefix is under your home dir."],"exampleFix":"// before\n$ yarn global add prettier\n→ Cannot create /usr/local/bin due to insufficient permissions.\n\n// after\n$ yarn config set prefix ~/.yarn-global\n$ yarn global add prettier","handlingStrategy":"validation","validationCode":"import fs from 'fs';\n\nfunction assertWritableBinFolder(binFolder: string): void {\n  try {\n    fs.accessSync(binFolder, fs.constants.W_OK);\n  } catch {\n    throw new Error(`${binFolder} is not writable by ${process.env.USER}; set yarn prefix to a user-owned dir`);\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await yarnGlobalAdd(pkg);\n} catch (e) {\n  if (/insufficient permissions/.test(e.message)) {\n    await reconfigurePrefixToUserDir(); // yarn config set prefix ~/.yarn-global\n    await yarnGlobalAdd(pkg);\n  } else throw e;\n}","preventionTips":["Set a user-owned `prefix` once: `yarn config set prefix ~/.yarn-global`.","Never use `sudo yarn global add`; it root-owns future files.","Use nvm/nodenv so node's prefix lives under your home directory."],"tags":["global","permissions","eacces","filesystem"],"backgroundTag":null,"analyzedSha":"c2dda503f3759b5be5f0e24ecd9cf5c97a540147","analyzedAt":"2026-08-13T04:17:06.305Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}