affaan-m/ECC · error · Error

destination is not writable by the current user: . Fix the…

Error message

${label} destination is not writable by the current user: ${candidatePath}. Fix the project ownership or permissions, then retry.

What it means

assertManagedDestinationsWritable checks with accessSync that every destination path in a managed install plan is writable (or readable as required) by the current user. When any access check fails, it throws, labeling the message 'Kimi' when the plan targets the kimi harness, otherwise 'Managed install'. It is a preflight guard so installs fail fast instead of half-completing on EACCES/ENOENT during writes.

Solutions

  1. Check ownership/permissions of candidatePath (ls -la) and chown or chmod so the current user has write access
  2. Verify you are running as the intended user (sudo down/up, wrong CI user)
  3. Confirm the path exists; create missing parent directories first
  4. Re-run the managed install after fixing permissions

Example fix

// before
$ whoami; ls -ld /project/.kimi
root root /project/.kimi   # not writable
// after
$ sudo chown -R $(whoami) /project/.kimi
Defensive patterns

Strategy: validation

Validate before calling

const fs = require('fs');
function assertWritable(path) {
  fs.accessSync(path, fs.constants.W_OK); // throws EACCES/ENOENT before install
}
// call for each plan.operations destination before preflight

Try / catch

try {
  await result(plan);
} catch (e) {
  if (/not writable by the current user/.test(e.message)) {
    console.error('Permission problem at:', e.message.match(/: ([^.]+)\./)[1]);
    // prompt to chown/chmod or run under correct user
  } else throw e;
}

Prevention

When it happens

Trigger: Calling preflightManagedPlan -> assertManagedDestinationsWritable with a plan whose destinationPath does not exist, or exists but lacks the required access mode for the current user (e.g. not owner, read-only directory, root-owned path).

Common situations: Running the installer under a user that doesn't own the project directory (e.g. checked out by root or another developer); CI containers with reduced permissions; read-only volume mounts; a typo'd or non-existent destination path.

Understand the failure class

Background: "Permission denied" / "Failed to write" file errors: why a library can't write its files to disk (EACCES, EPERM, ENOSPC) and how to fix them — this error's family across 43 libraries.

Related errors


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

Appendix: source

Thrown at scripts/lib/multi-harness-setup.js:335

  const accessSync = dependencies.accessSync || fs.accessSync;
  const destinationPaths = [
    ...plan.operations.map(operation => operation.destinationPath),
    ...(plan.installStatePath ? [plan.installStatePath] : []),
  ];
  const requirements = new Map();

  for (const destinationPath of destinationPaths) {
    const requirement = writableRequirement(destinationPath);
    const existingMode = requirements.get(requirement.candidatePath) || 0;
    requirements.set(requirement.candidatePath, existingMode | requirement.mode);
  }

  for (const [candidatePath, mode] of requirements) {
    try {
      accessSync(candidatePath, mode);
    } catch (_error) {
      const label = plan.target === 'kimi' ? 'Kimi' : 'Managed install';
      throw new Error(
        `${label} destination is not writable by the current user: ${candidatePath}. `
        + 'Fix the project ownership or permissions, then retry.'
      );
    }
  }
}

function preflightManagedPlan(plan, dependencies = {}) {
  if (!plan || !Array.isArray(plan.operations)) {
    throw new Error('A managed install plan with operations is required.');
  }
  if (typeof plan.installStatePath !== 'string' || plan.installStatePath.length === 0) {
    throw new Error('A managed install-state path is required before preflight.');
  }
  const ownership = readOwnedDestinations(plan, dependencies);
  const operations = plan.operations.map(operation => {
    assertSafeInstallOperation(plan, operation);
    return {

View on GitHub (pinned to 8321021c54)