vercel/turborepo · error · GeneratorError

Failed to run "${qualifiedName(generator)}" generator

Error message

Failed to run "${qualifiedName(generator)}" generator

What it means

Prompts succeeded but one or more plop actions failed during runActions. Each failure is logged first ('Error - <message>' / 'Error - <error>. Unable to <type> to "<path>"'), then turbo-gen throws GeneratorError `Failed to run "<workspace/name>" generator` (type plop_error_running_generator) to abort the run.

Source

Thrown at packages/turbo-gen/src/utils/plop.ts:394

  const answers = (await gen.runPrompts(bypassArgs)) as Array<unknown>;
  const results = await gen.runActions(
    { ...answers, ...injectTurborepoData({ project, generator: gen }) },
    {
      onComment: (comment: string) => {
        logger.dimmed(comment);
      }
    }
  );

  if (results.failures.length > 0) {
    for (const f of results.failures) {
      if (f instanceof Error) {
        logger.error(`Error - ${f.message}`);
      } else {
        logger.error(`Error - ${f.error}. Unable to ${f.type} to "${f.path}"`);
      }
    }
    throw new GeneratorError(
      `Failed to run "${qualifiedName(generator)}" generator`,
      { type: "plop_error_running_generator" }
    );
  }

  if (results.changes.length > 0) {
    logger.info("Changes made:");
    for (const c of results.changes) {
      if (c.path) {
        logger.item(`${c.path} (${c.type})`);
      }
    }
  }
}

View on GitHub (pinned to 9f94a7d215)

Solutions

  1. Read the per-failure lines printed just above the error — they state the action type, target path, and reason
  2. Fix the reported templatePath/glob, or update the modify action's pattern to match the current file content
  3. If re-generating over existing output, delete the previously generated files first (or configure the action with force/overwrite semantics deliberately)
  4. Re-run the generator after each fix; successful runs then print a 'Changes made:' list you can diff

Example fix

// generator action (before)
{ type: 'add', path: 'src/{{name}}.tsx', templateFile: './tmpl/comp.hbs' } // moved template
// after
{ type: 'add', path: 'src/{{name}}.tsx', templateFile: './templates/component.hbs' }
Defensive patterns

Strategy: try-catch

Validate before calling

import fs from 'node:fs';
import path from 'node:path';

function actionsAreRunnable(configDir: string, actions: Array<{ type: string; templateFile?: string; path: string }>): boolean {
  return actions.every((a) => {
    if (a.type === 'add' && a.templateFile && !fs.existsSync(path.join(configDir, a.templateFile))) return false;
    return true;
  });
}

Try / catch

try {
  await runCustomGenerator({ project, generator });
} catch (err) {
  if (err instanceof GeneratorError && err.type === 'plop_error_running_generator') {
    // per-action failures were already logged above the throw — inspect output,
    // clean up partially generated files, fix templates/patterns, then re-run once
    logger.warn('generator had failed actions; see per-file errors above');
  }
  throw err;
}

Prevention

When it happens

Trigger: An add/addMany action's templatePath is wrong or its glob matches nothing; a modify action's match pattern no longer occurs in the target file (fails when abortOnFail is set); the destination is not writable; the output file already exists and the config runs with force:false (the default set by createPlopFromConfig).

Common situations: Template files renamed/moved without updating paths; source files drifted so modify-action regexes no longer match; re-running a generator whose output files already exist.

Related errors


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