affaan-m/ECC · error

Nasiko install directory must be on a local filesystem.

Error message

Nasiko install directory must be on a local filesystem.

What it means

validateInstallDirectory rejects directories whose path begins with a Windows UNC prefix (\\, \\?\, or \\.\) because installs must land on a local filesystem, not a network share or device path. The regex matches these prefixes and throws this error.

Solutions

  1. Use a local-disk directory (e.g. C:\\Users\\me\\AppData\\Local\\nasiko\\bin).
  2. Map the share to a drive letter only if the underlying target is local — otherwise move the install to the local disk.
  3. Update config/scripts that hardcode a UNC path to a local absolute path.
  4. If the long-path \\\\?\ form is needed for a local path, use the plain absolute form instead.

Example fix

// before
await installDirectory({ os: 'windows', dir: '\\\\\\\\fileserver\\\\tools\\\\nasiko' });
// after
await installDirectory({ os: 'windows', dir: 'C:\\Users\\me\\AppData\\Local\\nasiko\\bin' });
Defensive patterns

Strategy: validation

Validate before calling

if (/^(?:\\\\|\\\\\?\\|\\\\\.\\)/.test(dir)) throw new Error('Install dir must be a local path, not a UNC/device path.');

Type guard

const isLocalPath = (d) => typeof d === 'string' && !/^(?:\\\\|\\\\\?\\|\\\\\.\\)/.test(d);

Try / catch

try { await installDirectory({ dir }); } catch (err) { if (err.message.includes('local filesystem')) throw new Error('Use a local disk path instead of ' + dir); throw err; }

Prevention

When it happens

Trigger: Passing an install directory like \\\\server\\share\\nasiko, \\\\?\\C\\... (long-path form), or \\\\.\\device... to installDirectory, parseMutationArguments, candidate, or parseStatusArguments — typically on Windows or with Windows-style paths.

Common situations: Corporate setups that home profiles or tool directories on network shares (SMB); users mapping a drive to a share and pasting the UNC path; Docker/CI volumes expressed as UNC paths on Windows.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/5ea1b260f529ded9. Report an issue: GitHub.

Appendix: source

Thrown at scripts/lib/nasiko-release.js:171

      response.on('end', () => resolve(Buffer.concat(chunks)));
      response.on('error', reject);
    });
    request.setTimeout(options.timeoutMs || 15000, () => request.destroy(new Error('Nasiko registry request timed out.')));
    request.on('error', reject);
  });
}

function defaultInstallDirectory(normalized, environment = process.env, homeDirectory = os.homedir()) {
  if (normalized.os === 'windows') {
    if (!environment.LOCALAPPDATA) throw new Error('LOCALAPPDATA is required on Windows.');
    return path.join(environment.LOCALAPPDATA, 'nasiko', 'bin');
  }
  return path.join(homeDirectory, '.local', 'bin');
}

function validateInstallDirectory(directory) {
  if (typeof directory !== 'string' || directory.includes('\0') || !path.isAbsolute(directory)) throw new Error('Nasiko install directory must be an absolute path.');
  if (/^(?:\\\\|\\\\\?\\|\\\\\.\\)/.test(directory)) throw new Error('Nasiko install directory must be on a local filesystem.');
  const resolved = path.resolve(directory);
  if (resolved === path.parse(resolved).root) throw new Error('Nasiko cannot install directly into a filesystem root.');
  let ancestor = resolved;
  while (!fs.existsSync(ancestor)) {
    const parent = path.dirname(ancestor);
    if (parent === ancestor) throw new Error('Nasiko install directory has no resolvable filesystem ancestor.');
    ancestor = parent;
  }
  const canonical = fs.realpathSync(ancestor);
  return path.join(canonical, path.relative(ancestor, resolved));
}

function assertPrivateInstallDirectory(directory) {
  const stats = fs.lstatSync(directory);
  if (!stats.isDirectory() || stats.isSymbolicLink()) throw new Error('Nasiko install directory must be a real directory, not a symlink.');
  if (process.platform !== 'win32') {
    if (typeof process.getuid === 'function' && stats.uid !== process.getuid()) throw new Error('Nasiko install directory must be owned by the current user.');
    if ((stats.mode & 0o022) !== 0) throw new Error('Nasiko install directory must not be group- or world-writable.');

View on GitHub (pinned to 8321021c54)