google-gemini/gemini-cli · error · Error
Cannot write extension settings to ${envFilePath} because it
Error message
Cannot write extension settings to ${envFilePath} because it is a directory. What it means
Thrown by the bulk write path (saveExtensionSettings / formatEnvContent caller) when the target env file path already exists and is a directory. The code stat()s envFilePath before fs.writeFile and refuses to overwrite a directory, because writing a file over a folder would either fail or corrupt the layout.
Source
Thrown at packages/cli/src/config/extensions/extensionSettings.ts:132
const nonSensitiveSettings: Record<string, string> = {};
for (const setting of settings) {
const value = allSettings[setting.envVar];
if (value === undefined || value === '') {
continue;
}
if (setting.sensitive) {
await keychain.setSecret(setting.envVar, value);
} else {
nonSensitiveSettings[setting.envVar] = value;
}
}
const envContent = formatEnvContent(nonSensitiveSettings);
if (fsSync.existsSync(envFilePath)) {
const stat = fsSync.statSync(envFilePath);
if (stat.isDirectory()) {
throw new Error(
`Cannot write extension settings to ${envFilePath} because it is a directory.`,
);
}
}
await fs.writeFile(envFilePath, envContent);
}
function formatEnvContent(settings: Record<string, string>): string {
let envContent = '';
for (const [key, value] of Object.entries(settings)) {
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(key)) {
throw new Error(
`Invalid environment variable name: "${key}". Must contain only alphanumeric characters and underscores.`,
);
}
if (value.includes('\n') || value.includes('\r')) {
throw new Error(View on GitHub (pinned to 5024443c72)
Solutions
- Inspect envFilePath and remove or rename the directory blocking the write.
- Change the storage location so the settings file does not collide with an existing directory.
- Add a pre-write stat check in the caller and surface a clearer prompt before this throw.
Example fix
// before
await fs.writeFile(envFilePath, envContent); // throws if envFilePath is a dir
// after
if (fsSync.existsSync(envFilePath) && fsSync.statSync(envFilePath).isDirectory()) {
throw new Error(`Refusing to overwrite directory at ${envFilePath}; remove it first.`);
}
await fs.writeFile(envFilePath, envContent); Defensive patterns
Strategy: validation
Validate before calling
import fsSync from 'node:fs';
function ensureWritableFile(envFilePath: string) {
if (fsSync.existsSync(envFilePath) && fsSync.statSync(envFilePath).isDirectory()) {
throw new Error(`${envFilePath} is a directory, not a writable file`);
}
} Try / catch
try { await saveExtensionSettings(...); } catch (e) { if (String(e).includes('because it is a directory')) { /* prompt user to remove dir */ } throw e; } Prevention
- Treat the settings file location as reserved; never create directories with the same name.
- Run a stat-check before bulk write in your own wrapper to give a clearer message.
When it happens
Trigger: A directory named EXTENSION_SETTINGS_FILENAME (e.g. .env) already exists at the location returned by getEnvFilePath (workspace dir or ExtensionStorage env file path). Reached when writing all non-sensitive extension settings at once.
Common situations: A user or script manually created a folder named like the env settings file; a previous tooling bug created a directory where a file was expected; a symlink loop resolves to a directory.
Related errors
- Invalid environment variable name: "${key}". Must contain on
- Invalid environment variable value for "${key}". Values cann
- Workspace path ${resolvedPath} does not exist
- Workspace path ${resolvedPath} is not a directory
- Path already exists: ${path}
AI-assisted analysis of google-gemini/gemini-cli@5024443c72 (2026-08-12).
Data as JSON: /api/errors/0f964028870a2eb3.
Report an issue: GitHub.