{"record":{"id":"78278a16710ca242","repo":"remix-run/remix","slug":"target-path-is-not-a-directory-targetdir","errorCode":null,"errorMessage":"Target path is not a directory: ${targetDir}","messagePattern":"Target path is not a directory: (.+?)","errorType":"exception","errorClass":"UsageError","httpStatus":null,"severity":"error","filePath":"packages/cli/src/lib/bootstrap-project.ts","lineNumber":169,"sourceCode":"  }\n  packageJson.devDependencies = {\n    ...packageJson.devDependencies,\n    '@types/node': 'latest',\n    typescript: 'latest',\n  }\n  packageJson.engines = {\n    ...packageJson.engines,\n    node: `>=${MINIMUM_SUPPORTED_NODE_VERSION}`,\n  }\n\n  await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\\n', 'utf8')\n}\n\nasync function ensureTargetDirectory(targetDir: string, force: boolean): Promise<void> {\n  try {\n    let stats = await fs.stat(targetDir)\n    if (!stats.isDirectory()) {\n      throw targetPathNotDirectory(targetDir)\n    }\n\n    let entries = await fs.readdir(targetDir)\n    if (entries.length > 0 && !force) {\n      throw targetDirectoryNotEmpty(targetDir)\n    }\n  } catch (error) {\n    let nodeError = error as NodeJS.ErrnoException\n    if (nodeError.code !== 'ENOENT') {\n      throw error\n    }\n  }\n\n  await fs.mkdir(targetDir, { recursive: true })\n}\n\nasync function copyTemplateDirectory({\n  sourceDir,","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/remix-run/remix/blob/9696913134be3a4423513d2775f7b31d6917c049/packages/cli/src/lib/bootstrap-project.ts#L151-L187","documentation":"Project bootstrap requires the target path to be a directory, but fs.stat succeeded and reported something else (a file, socket, etc.). Scaffolding refuses to write a project into a path occupied by a non-directory.","triggerScenarios":"ensureTargetDirectory stats the resolved targetDir and it exists but is a regular file or other non-directory entry, e.g. remix new notes where ./notes is an existing file.","commonSituations":"A file with the same name as the intended project directory already exists (README, lockfile, symlink to a file); scripts that pre-create a marker file at the target path.","solutions":["Choose a different target directory name","Delete or rename the existing file occupying the path","If it is a symlink to a file, remove or retarget it"],"exampleFix":"# before\n$ touch myapp && remix new myapp\n\n# after\n$ rm myapp && remix new myapp","handlingStrategy":"type-guard","validationCode":"import { statSync } from 'node:fs'\n\nfunction targetIsDirectory(p: string): boolean {\n  try { return statSync(p).isDirectory() } catch { return true } // ENOENT is fine for scaffolding\n}","typeGuard":"function isSafeBootstrapTarget(p: string): boolean {\n  try {\n    let s = statSync(p)\n    return s.isDirectory() || s.isFile() === false\n  } catch { return true }\n}","tryCatchPattern":"try {\n  await bootstrapProject(opts)\n} catch (error) {\n  if (/not a directory/i.test(error.message)) chooseAnotherName()\n  else throw error\n}","preventionTips":["Check the target path is not an existing file before scaffolding","Generate project names that cannot collide with files (fresh subdirectory names)","In scripts, fail fast if the target exists and is not a directory"],"tags":["cli","scaffolding","filesystem"],"backgroundTag":"path-exists-conflict","analyzedSha":"9696913134be3a4423513d2775f7b31d6917c049","analyzedAt":"2026-08-27T19:55:01.024Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}