{"record":{"id":"73e15451b5383708","repo":"vercel/turborepo","slug":"config-directory-already-exists","errorCode":"config_directory_already_exists","errorMessage":"Generator config directory already exists at ${configDirectory}","messagePattern":"Generator config directory already exists at (.+?)","errorType":"exception","errorClass":"GeneratorError","httpStatus":null,"severity":"warning","filePath":"packages/turbo-gen/src/utils/setup-from-template.ts","lineNumber":25,"sourceCode":"export async function setupFromTemplate({\n  project,\n  template\n}: {\n  project: Project;\n  template: \"ts\" | \"js\";\n}) {\n  const configDirectory = path.join(project.paths.root, \"turbo\", \"generators\");\n\n  const templateKey = `simple-${template}`;\n  const embeddedTemplate = TEMPLATES[templateKey];\n  if (!embeddedTemplate) {\n    throw new GeneratorError(`Unknown template \"${templateKey}\"`, {\n      type: \"config_directory_already_exists\"\n    });\n  }\n\n  if (await fs.pathExists(configDirectory)) {\n    throw new GeneratorError(\n      `Generator config directory already exists at ${configDirectory}`,\n      { type: \"config_directory_already_exists\" }\n    );\n  }\n\n  for (const file of embeddedTemplate.files) {\n    const filePath = path.join(configDirectory, file.relativePath);\n    await fs.outputFile(filePath, file.content);\n  }\n}\n","sourceCodeStart":7,"sourceCodeEnd":36,"githubUrl":"https://github.com/vercel/turborepo/blob/f9245100cf0d31d96628804ead485f6bf226e55a/packages/turbo-gen/src/utils/setup-from-template.ts#L7-L36","documentation":"setup-from-template creates the turbo/generators directory at your project root from an embedded template. It throws this GeneratorError with code config_directory_already_exists when that directory already exists, so it never overwrites your generator configs. The same function also rejects unknown template names with the same error code.","triggerScenarios":"You run the setup flow (for example turbo gen onboarding) in a repository that already has a turbo/generators folder. fs.pathExists(configDirectory) is true, so it throws before writing any template file.","commonSituations":"Running the generator setup twice. A teammate already added custom generators. A template config committed earlier under turbo/generators.","solutions":["If the existing turbo/generators content is disposable, remove or rename it and run setup again","If you want to keep it, skip setup and add the new generator files manually into turbo/generators","Inspect the existing directory first so you do not delete custom plopfiles by accident"],"exampleFix":"# before: directory already present\nmv turbo/generators turbo/generators.bak  # keep a backup\n# then re-run setup\nnpm exec turbo gen\n# after: restore your custom generators into the new directory if needed\ncp turbo/generators.bak/config.ts turbo/generators/config.ts","handlingStrategy":"validation","validationCode":"import fs from \"fs-extra\";\nimport path from \"node:path\";\n\n// check before setup so existing generator configs are never clobbered\nconst configDirectory = path.join(repoRoot, \"turbo\", \"generators\");\nif (await fs.pathExists(configDirectory)) {\n  throw new Error(`Generator config directory already exists at ${configDirectory}`);\n}","typeGuard":"async function hasGeneratorConfig(repoRoot: string): Promise<boolean> {\n  return fs.pathExists(path.join(repoRoot, \"turbo\", \"generators\"));\n}","tryCatchPattern":"try {\n  await setupFromTemplate({ project, template });\n} catch (err) {\n  if (err instanceof GeneratorError && err.type === \"config_directory_already_exists\") {\n    // keep existing configs; skip setup instead of failing the whole flow\n    console.warn(\"Generator config already present; skipping template setup.\");\n  } else {\n    throw err;\n  }\n}","preventionTips":["Run generator setup only once per repository","Track turbo/generators in version control so setup state is visible","Move aside or merge existing generator directories before re-running setup"],"tags":["turbo-gen","setup","directory-exists","generators"],"backgroundTag":"directory-already-exists","analyzedSha":"f9245100cf0d31d96628804ead485f6bf226e55a","analyzedAt":"2026-08-17T10:46:15.696Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}