vercel/turborepo · error · GeneratorError

Unknown template "${templateKey}"

Error message

Unknown template "${templateKey}"

What it means

setupFromTemplate materializes the embedded generator templates under turbo/generators, keyed `simple-ts` / `simple-js` from the `template` argument (typed 'ts' | 'js'). If the TEMPLATES map lacks that key, this GeneratorError is thrown — in practice an internal invariant, since the templates ship embedded with @turbo/gen. Hitting it means a broken/partial install, a version-skewed build, or a programmatic caller bypassing the 'ts'|'js' type. (Note: the error's `type` is mislabeled 'config_directory_already_exists'.)

Source

Thrown at packages/turbo-gen/src/utils/setup-from-template.ts:19

import path from "node:path";
import type { Project } from "@turbo/workspaces";
import fs from "fs-extra";
import { GeneratorError } from "./error";
import { TEMPLATES } from "../templates/embedded";

export async function setupFromTemplate({
  project,
  template
}: {
  project: Project;
  template: "ts" | "js";
}) {
  const configDirectory = path.join(project.paths.root, "turbo", "generators");

  const templateKey = `simple-${template}`;
  const embeddedTemplate = TEMPLATES[templateKey];
  if (!embeddedTemplate) {
    throw new GeneratorError(`Unknown template "${templateKey}"`, {
      type: "config_directory_already_exists"
    });
  }

  if (await fs.pathExists(configDirectory)) {
    throw new GeneratorError(
      `Generator config directory already exists at ${configDirectory}`,
      { type: "config_directory_already_exists" }
    );
  }

  for (const file of embeddedTemplate.files) {
    const filePath = path.join(configDirectory, file.relativePath);
    await fs.outputFile(filePath, file.content);
  }
}

View on GitHub (pinned to 9f94a7d215)

Solutions

  1. Reinstall cleanly: remove node_modules and lockfile artifacts for the turbo CLI / @turbo/gen and reinstall (`npm i -g turbo@latest` or retry `npx turbo@latest gen init`)
  2. If calling programmatically, pass only 'ts' or 'js' as the template value
  3. If it persists on a clean install, report upstream — include that the error type string is 'config_directory_already_exists', a known mislabel for this branch

Example fix

// before (programmatic caller)
setupFromTemplate({ project, template: 'typescript' as unknown as 'ts' });
// after
setupFromTemplate({ project, template: 'ts' });
Defensive patterns

Strategy: type-guard

Validate before calling

const SUPPORTED_TEMPLATES = new Set(['ts', 'js']);

function isSupportedTemplate(t: string): boolean {
  return SUPPORTED_TEMPLATES.has(t);
}
// programmatic callers: if (!isSupportedTemplate(t)) throw before setupFromTemplate

Type guard

function isTemplateKind(t: string): t is 'ts' | 'js' {
  return t === 'ts' || t === 'js';
}

Try / catch

try {
  await setupFromTemplate({ project, template });
} catch (err) {
  if (err instanceof GeneratorError && /Unknown template/.test(err.message)) {
    // internal invariant broken: reinstall the CLI package cleanly and retry once
    throw new Error('embedded generator templates missing — reinstall turbo/@turbo/gen');
  }
  throw err;
}

Prevention

When it happens

Trigger: A corrupted or incomplete @turbo/gen / turbo CLI install missing the embedded template files; a custom build where the templates embedding step did not run; calling setupFromTemplate programmatically with a value other than 'ts' or 'js' despite the type annotation.

Common situations: Almost exclusively internal: tampered installs, patched node_modules, or downstream forks that regenerate the templates map; ordinary CLI users should not see it.

Related errors


AI-assisted analysis of vercel/turborepo@9f94a7d215 (2026-08-16). Data as JSON: /api/errors/b9bbc96aca89f460. Report an issue: GitHub.