google-gemini/gemini-cli · error · Error

Unable to create ${dirPath} directory. Do you have file perm

Error message

Unable to create ${dirPath} directory. Do you have file permissions in the current directory?

What it means

Thrown by createDirectory() when fs.promises.mkdir(dirPath, { recursive: true }) rejects — typically the .github/workflows directory (or another target) could not be created. The underlying error is logged via debugLogger before this generic message is thrown.

Source

Thrown at packages/cli/src/ui/commands/setupGithubCommand.ts:176

          flush: true,
        });

        await body.pipeTo(Writable.toWeb(fileStream));
      })(),
    );
  }

  await Promise.all(downloads).finally(() => {
    abortController.abort();
  });
}

async function createDirectory(dirPath: string): Promise<void> {
  try {
    await fs.promises.mkdir(dirPath, { recursive: true });
  } catch (error) {
    debugLogger.debug(`Failed to create ${dirPath} directory:`, error);
    throw new Error(
      `Unable to create ${dirPath} directory. Do you have file permissions in the current directory?`,
    );
  }
}

async function downloadSetupFiles({
  configs,
  releaseTag,
  proxy,
}: {
  configs: Array<{ paths: string[]; targetDir: string }>;
  releaseTag: string;
  proxy: string | undefined;
}): Promise<void> {
  try {
    await Promise.all(
      configs.map(({ paths, targetDir }) => {
        const abortController = new AbortController();

View on GitHub (pinned to 5024443c72)

Solutions

  1. Check write permissions on the repo root and parent of .github/workflows (`ls -la` and try `touch` a test file).
  2. Run the CLI with appropriate filesystem permissions / as a user that can write to the repo.
  3. If the disk is full, free space (df -h) and retry.
  4. Confirm the repo root path returned by git is writable and not on a read-only mount.
Defensive patterns

Strategy: validation

Validate before calling

import fs from 'node:fs';
async function isWritableDir(dirPath: string): Promise<boolean> {
  try {
    await fs.promises.access(path.dirname(dirPath), fs.constants.W_OK);
    return true;
  } catch { return false; }
}

Type guard

function isMkdirError(e: unknown): boolean {
  return e instanceof Error && /Unable to create .* directory/.test(e.message);
}

Try / catch

try {
  await runSetupGithub(ctx);
} catch (e) {
  if (e instanceof Error && /Unable to create .* directory/.test(e.message)) {
    // check write permissions / disk space on the repo root and retry
  }
  throw e;
}

Prevention

When it happens

Trigger: mkdir with recursive:true throws inside createDirectory(); the catch wraps any filesystem error (EACCES, EROFS, ENOSPC, ENAMETOOLONG) and rethrows this message.

Common situations: The git repo root is on a read-only filesystem or the user lacks write permission; the target path is invalid/locked; the disk is full; running /setup-github in a directory the process cannot write to.

Related errors


AI-assisted analysis of google-gemini/gemini-cli@5024443c72 (2026-08-12). Data as JSON: /api/errors/40188d3f6196f5b5. Report an issue: GitHub.