{"record":{"id":"18b3504ffe252cc5","repo":"google-gemini/gemini-cli","slug":"path-already-exists-path","errorCode":null,"errorMessage":"Path already exists: ${path}","messagePattern":"Path already exists: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/cli/src/commands/extensions/new.ts","lineNumber":35,"sourceCode":"}\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nconst EXAMPLES_PATH = join(__dirname, 'examples');\n\nasync function pathExists(path: string) {\n  try {\n    await access(path);\n    return true;\n  } catch {\n    return false;\n  }\n}\n\nasync function createDirectory(path: string) {\n  if (await pathExists(path)) {\n    throw new Error(`Path already exists: ${path}`);\n  }\n  await mkdir(path, { recursive: true });\n}\n\nasync function copyDirectory(template: string, path: string) {\n  await createDirectory(path);\n\n  const examplePath = join(EXAMPLES_PATH, template);\n  const entries = await readdir(examplePath, { withFileTypes: true });\n  for (const entry of entries) {\n    const srcPath = join(examplePath, entry.name);\n    const destPath = join(path, entry.name);\n    await cp(srcPath, destPath, { recursive: true });\n  }\n}\n\nasync function handleNew(args: NewArgs) {\n  if (args.template) {","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/google-gemini/gemini-cli/blob/5024443c7217464a66e98f80d73172a26440bd8f/packages/cli/src/commands/extensions/new.ts#L17-L53","documentation":"createDirectory() in the 'gemini extensions new' command checks if the target path already exists (via fs.access) before creating it. If the path exists, it throws to prevent silently overwriting an existing directory or extension. The check runs before mkdir.","triggerScenarios":"Running 'gemini extensions new ./my-ext' when ./my-ext already exists on disk. The pathExists() helper uses access() which succeeds for any existing filesystem entry.","commonSituations":"Re-running the new command after a previous attempt; typo causing path collision with an existing extension; leftover directory from a failed or abandoned creation.","solutions":["Choose a different path that doesn't exist yet.","Remove or rename the existing directory first: rm -rf ./my-ext.","Verify the intended path is available before running."],"exampleFix":"// before\ngemini extensions new ./my-ext  // ./my-ext already exists\n\n// after\nrm -rf ./my-ext && gemini extensions new ./my-ext","handlingStrategy":"validation","validationCode":"import { access } from 'node:fs/promises';\n\nasync function pathIsFree(path: string): Promise<boolean> {\n  try {\n    await access(path);\n    return false; // exists\n  } catch {\n    return true; // free\n  }\n}\n\n// Before running new:\nif (!(await pathIsFree(targetPath))) {\n  throw new Error(`Remove or rename existing path: ${targetPath}`);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Choose a unique path for each new extension.","Clean up failed or abandoned extension directories before re-running.","Check path availability before scripting the new command."],"tags":["cli","extensions","new","filesystem"],"backgroundTag":null,"analyzedSha":"5024443c7217464a66e98f80d73172a26440bd8f","analyzedAt":"2026-08-12T06:01:53.711Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}