angular/angular-cli · error · Error

Failed to append autocompletion setup to `${rcFile}`.

Error message

Failed to append autocompletion setup to `${rcFile}`.

What it means

When appending the autocompletion bootstrap line (`source <(ng completion script)`) to the chosen shell RC file, an I/O failure from `fs.appendFile` is caught, wrapped via `assertIsError`, and rethrown with this message and the original error as `cause`. It means the CLI could not write to the RC file, not that autocompletion itself failed.

Source

Thrown at packages/angular/cli/src/utilities/completion.ts:247

  // Get the first file that already exists or fallback to a new file of the first candidate.
  const candidates = await Promise.allSettled(
    runCommandCandidates.map((rcFile) => fs.access(rcFile).then(() => rcFile)),
  );
  const rcFile =
    candidates.find(
      (result): result is PromiseFulfilledResult<string> => result.status === 'fulfilled',
    )?.value ?? runCommandCandidates[0];

  // Append Angular autocompletion setup to RC file.
  try {
    await fs.appendFile(
      rcFile,
      '\n\n# Load Angular CLI autocompletion.\nsource <(ng completion script)\n',
    );
  } catch (err) {
    assertIsError(err);
    throw new Error(`Failed to append autocompletion setup to \`${rcFile}\`.`, { cause: err });
  }

  return rcFile;
}

/** Returns an ordered list of possible candidates of RC files used by the given shell. */
function getShellRunCommandCandidates(shell: string, home: string): string[] | undefined {
  if (shell.toLowerCase().includes('bash')) {
    return ['.bashrc', '.bash_profile', '.profile'].map((file) => path.join(home, file));
  } else if (shell.toLowerCase().includes('zsh')) {
    return ['.zshrc', '.zsh_profile', '.profile'].map((file) => path.join(home, file));
  } else {
    return undefined;
  }
}

/**
 * Returns whether the user has a global CLI install.

View on GitHub (pinned to bb72145f9a)

Solutions

  1. Fix permissions on the RC file: `chmod u+w ~/.bashrc` (or take ownership with `chown`).
  2. Check `err.cause` (the underlying Node error) to see the precise filesystem failure (EACCES, EROFS, EISDIR, ENOSPC).
  3. Append the line manually if the CLI cannot: add `source <(ng completion script)` to your `~/.bashrc`/`~/.zshrc`.
  4. Free disk space or remount the filesystem read-write if ENOSPC/EROFS is reported.

Example fix

// inspect the wrapped cause
try { await ngCompletion(); } catch (e) {
  console.error(e.cause); // e.g. EACCES: permission denied, open '/home/user/.bashrc'
}
// shell fix
chmod u+w ~/.bashrc
Defensive patterns

Strategy: try-catch

Validate before calling

import { access, constants } from 'node:fs/promises';
await access(rcFile, constants.W_OK); // throws early if the RC file is not writable

Type guard

function isWriteError(e: unknown): e is Error & { code?: string } {
  return e instanceof Error && typeof (e as NodeJS.ErrnoException).code === 'string';
}

Try / catch

try {
  await ngCompletionSetup();
} catch (e: any) {
  if (e instanceof Error && e.message.startsWith('Failed to append autocompletion setup')) {
    console.error('Underlying cause:', e.cause); // Node errno (EACCES, EROFS, ...)
    // fallback: append the source line manually
  } else { throw e; }
}

Prevention

When it happens

Trigger: `initializeAutocomplete` calling `fs.appendFile(rcFile, ...)` which rejects due to permissions, a read-only filesystem, the path being a directory, or disk-full conditions.

Common situations: Home directory or RC file owned by another user / read-only permissions; running inside a container with a read-only `$HOME`; network home directories (NFS) unavailable; `$HOME` pointing to a non-writable path.

Related errors


AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30). Data as JSON: /api/errors/7ce0654c3d7b67bb. Report an issue: GitHub.