{"record":{"id":"c80476b834c4747f","repo":"mastra-ai/mastra","slug":"directory-path-basename-targetpath-already-exi","errorCode":null,"errorMessage":"Directory ${path.basename(targetPath)} already exists","messagePattern":"Directory (.+?) already exists","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mastracode/mastra-factory/src/utils/clone.ts","lineNumber":42,"sourceCode":"    await fs.access(filePath);\n    return true;\n  } catch (error) {\n    if ((error as NodeJS.ErrnoException).code === 'ENOENT') return false;\n    throw error;\n  }\n}\n\nasync function directoryExists(dirPath: string): Promise<boolean> {\n  try {\n    return (await fs.stat(dirPath)).isDirectory();\n  } catch {\n    return false;\n  }\n}\n\nexport async function cloneTemplate(repoUrl: string, targetPath: string): Promise<void> {\n  if (await pathExists(targetPath)) {\n    throw new Error(`Directory ${path.basename(targetPath)} already exists`);\n  }\n\n  const tempRoot = await fs.mkdtemp(path.join(path.dirname(targetPath), `.${path.basename(targetPath)}-`));\n  const tempTarget = path.join(tempRoot, 'template');\n\n  try {\n    try {\n      const degitRepo = repoUrl.replace('https://github.com/', '');\n      await x('npx', ['degit', degitRepo, tempTarget], {\n        throwOnError: true,\n        nodeOptions: { cwd: process.cwd() },\n      });\n\n      if ((await fs.readdir(tempTarget)).length === 0) {\n        throw new Error('degit completed without cloning template files');\n      }\n    } catch {\n      await fs.rm(tempTarget, { recursive: true, force: true });","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/mastra-factory/src/utils/clone.ts#L24-L60","documentation":"cloneTemplate clones the template repository into targetPath via a temp directory. Before doing any work it checks pathExists(targetPath); if a directory (or file) already exists at the destination, it throws immediately instead of overwriting user data — a deliberate safety guard.","triggerScenarios":"Running `create-factory` (or cloneTemplate) with a targetPath that already exists on disk — e.g. a previous partial/complete scaffold, or an unrelated directory at that path.","commonSituations":"Re-running the scaffold command in the same folder after an earlier run; a crashed previous run left a `.target-` temp dir plus a recreated target; user pre-created the project folder (e.g. via mkdir or git clone); IDE-generated folders occupying the name.","solutions":["Choose a new targetPath or rename/remove the existing directory, then rerun.","Inspect the existing directory first — if it's a leftover failed run, delete it manually (also clean sibling `.target-*` temp dirs).","Rerun inside a different, empty parent directory.","If the existing directory is empty and safe, delete it with `rm -rf <dir>` before re-running."],"exampleFix":"// before\n$ create-factory ./my-app\n// Error: Directory my-app already exists\n// after\n$ rm -rf ./my-app            # or: mv ./my-app ./my-app.bak\n$ create-factory ./my-app","handlingStrategy":"validation","validationCode":"import { pathExists } from './utils/clone';\nif (await pathExists(targetPath)) {\n  const alt = `${targetPath}-${Date.now()}`;\n  console.warn(`'${targetPath}' exists — using '${alt}' instead.`);\n  targetPath = alt;\n}\nawait cloneTemplate(repoUrl, targetPath);","typeGuard":null,"tryCatchPattern":"try {\n  await cloneTemplate(repoUrl, targetPath);\n} catch (err) {\n  if (err.message.includes('already exists')) {\n    const backup = `${targetPath}.bak-${Date.now()}`;\n    await fs.rename(targetPath, backup);\n    console.log(`Moved existing directory to ${backup}; retrying clone.`);\n    await cloneTemplate(repoUrl, targetPath);\n  } else throw err;\n}","preventionTips":["Run the scaffold only in empty directories; check with ls before invoking.","Clean up leftover `.target-*` temp dirs from crashed runs before re-running.","Let the CLI pick/generate the target directory in scripts rather than hardcoding one.","Back up (rename) instead of deleting an existing directory when rerunning."],"tags":["filesystem","cli","conflict","scaffolding"],"backgroundTag":"directory-already-exists","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}