{"record":{"id":"4a6d130c71bbb40d","repo":"affaan-m/ECC","slug":"nasiko-install-directory-must-not-be-group-or-wor","errorCode":null,"errorMessage":"Nasiko install directory must not be group- or world-writable.","messagePattern":"Nasiko install directory must not be group- or world-writable\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/lib/nasiko-release.js","lineNumber":189,"sourceCode":"  if (/^(?:\\\\\\\\|\\\\\\\\\\?\\\\|\\\\\\\\\\.\\\\)/.test(directory)) throw new Error('Nasiko install directory must be on a local filesystem.');\n  const resolved = path.resolve(directory);\n  if (resolved === path.parse(resolved).root) throw new Error('Nasiko cannot install directly into a filesystem root.');\n  let ancestor = resolved;\n  while (!fs.existsSync(ancestor)) {\n    const parent = path.dirname(ancestor);\n    if (parent === ancestor) throw new Error('Nasiko install directory has no resolvable filesystem ancestor.');\n    ancestor = parent;\n  }\n  const canonical = fs.realpathSync(ancestor);\n  return path.join(canonical, path.relative(ancestor, resolved));\n}\n\nfunction assertPrivateInstallDirectory(directory) {\n  const stats = fs.lstatSync(directory);\n  if (!stats.isDirectory() || stats.isSymbolicLink()) throw new Error('Nasiko install directory must be a real directory, not a symlink.');\n  if (process.platform !== 'win32') {\n    if (typeof process.getuid === 'function' && stats.uid !== process.getuid()) throw new Error('Nasiko install directory must be owned by the current user.');\n    if ((stats.mode & 0o022) !== 0) throw new Error('Nasiko install directory must not be group- or world-writable.');\n  }\n}\n\nfunction metadataPathFor(executable) { return path.join(path.dirname(executable), METADATA_FILENAME); }\n\nfunction readBoundedRegularFile(filePath, maximumBytes) {\n  const noFollow = fs.constants.O_NOFOLLOW;\n  const descriptor = fs.openSync(filePath, fs.constants.O_RDONLY | (noFollow || 0));\n  try {\n    const stats = fs.fstatSync(descriptor);\n    if (!stats.isFile() || stats.size <= 0 || stats.size > maximumBytes) return null;\n    if (!noFollow) {\n      const pathStats = fs.lstatSync(filePath);\n      if (pathStats.isSymbolicLink()\n        || pathStats.dev !== stats.dev\n        || pathStats.ino !== stats.ino\n        || pathStats.birthtimeMs !== stats.birthtimeMs) {\n        const error = new Error('Nasiko managed files must not be symbolic links or reparse points.');","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/nasiko-release.js#L171-L207","documentation":"On non-Windows platforms the library requires the install directory's permission bits to exclude group-write and other-write (mode & 0o022 === 0). If the directory is group- or world-writable, it throws this error, because any local user could replace the installed binary between verification and execution.","triggerScenarios":"installNasiko or uninstallNasiko where lstat on the install directory shows mode bits 0o022 set — e.g. a directory created with mode 0777 or 0775, or a umask that left group/other write enabled.","commonSituations":"Creating the directory with `mkdir -m 777`; shared team servers where bin directories are group-writable; copying a directory from a FAT/exFAT mount that defaults to 0777; overly permissive umask (0000) in CI.","solutions":["Tighten permissions: `chmod go-w <dir>` (or `chmod 755 <dir>`), then retry.","Check and fix your umask (e.g. `umask 022`) before creating install directories.","Create a fresh directory with restrictive defaults: `mkdir -m 755 <dir>`.","Verify with `stat -c '%a' <dir>` that group/other write bits are clear."],"exampleFix":"// before\nls -ld ~/.local/bin  # drwxrwxrwx\ninstallNasiko({ yes: true })\n// after\nchmod 755 ~/.local/bin\ninstallNasiko({ yes: true })","handlingStrategy":"validation","validationCode":"const mode = fs.statSync(dir).mode & 0o777\nif ((mode & 0o022) !== 0) throw new Error(`installDir too permissive: ${mode.toString(8)}`)","typeGuard":null,"tryCatchPattern":"try {\n  await installNasiko({ installDir: dir, yes: true })\n} catch (e) {\n  if (e.message.includes('group- or world-writable')) {\n    fs.chmodSync(dir, 0o755)\n    return installNasiko({ installDir: dir, yes: true })\n  }\n  throw e\n}","preventionTips":["Create install directories with mode 755 explicitly (mkdir -m 755).","Set umask 022 in shell profiles and CI.","Avoid directories on FAT/exFAT mounts that force 0777.","Audit permissions with `stat -c '%a'` before custom install paths."],"tags":["permissions","security","unix","install-directory"],"backgroundTag":"insufficient-permissions","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}