vercel/turborepo · error · GeneratorError

Failed to run generator

Error message

Failed to run generator

What it means

turbo-gen's custom generator runner executes your plop-based generator config (turbo/generators/config.ts). Any exception escaping that run which is not already a GeneratorError — a throw inside prompts/actions, a missing template file, an invalid action definition — is captured and rethrown as GeneratorError 'Failed to run generator' (type plop_error_running_generator), carrying the underlying error's message.

Source

Thrown at packages/turbo-gen/src/generators/custom.ts:88

    await runCustomGenerator({
      project,
      generator: selectedGenerator,
      bypassArgs: opts.args,
      configPath: opts.config
    });
  } catch (err) {
    // pass any GeneratorErrors through to root
    if (err instanceof GeneratorError) {
      throw err;
    }

    // capture any other errors and throw as GeneratorErrors
    let message = "Failed to run generator";
    if (err instanceof Error) {
      message = err.message;
    }

    throw new GeneratorError(message, {
      type: "plop_error_running_generator"
    });
  } finally {
    if (isOnboarding) {
      logger.log();
      logger.info(`Congrats! You just ran your first Turborepo generator`);
      logger.dimmed(
        "Learn more about custom Turborepo generators - https://turborepo.dev/docs/guides/generating-code#custom-generators"
      );
    }
  }

  logger.log();
  logger.bold(logger.turboGradient(">>> Success!"));
}

View on GitHub (pinned to 9f94a7d215)

Solutions

  1. Read the GeneratorError message — it is the underlying err.message and names the real fault (usually the missing template path or action type)
  2. Reproduce config-load errors standalone: `npx tsx turbo/generators/config.ts` (or bundle with esbuild) to surface syntax/type errors the CLI swallows
  3. Verify every templatePath is correct relative to the config file (`ls` each referenced path)
  4. Check action types against node-plop's supported set (add, addMany, modify, append, move, copy) and that helpers/partials are registered before use

Example fix

// turbo/generators/config.ts (before)
plop.setActionType('scaffold', ...) // typo'd action used below
actions.push({ type: 'scaffod', ... })
// after
actions.push({ type: 'scaffold', ... })
Defensive patterns

Strategy: try-catch

Validate before calling

import fs from 'node:fs';

function templatePathsExist(configDir: string, templatePaths: string[]): boolean {
  return templatePaths.every((t) => fs.existsSync(`${configDir}/${t}`));
}

Try / catch

try {
  await runCustomGenerator({ project, generator });
} catch (err) {
  if (err instanceof GeneratorError && err.type === 'plop_error_running_generator') {
    // err.message is the underlying cause: log it with full detail and stop — do not blindly retry
    logger.error(`generator crashed: ${err.message}`);
    throw err;
  }
  throw err;
}

Prevention

When it happens

Trigger: The generator config throws at runtime during plop execution; an `add`/`addMany` action references a templatePath that does not exist; an unknown action type string; a helper/partial used but never registered; TS/ESM issues that survived the esbuild bundling fallback.

Common situations: Hand-written generator configs after refactors move template files without updating paths; installing new deps in the config without adding them to the workspace; typos in action type names like 'modifiy'.

Related errors


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