vercel/turborepo · error · GeneratorError
plop_unable_to_load_config
plop_unable_to_load_config
Error message
Unable to load generators
What it means
turbo-gen loads your generator config by bundling it with esbuild and handing it to node-plop. createPlopFromConfig returns undefined when node-plop rejects the config, logs the underlying error, and cleans up the bundled file. This GeneratorError with code plop_unable_to_load_config is thrown when that load produced no plop instance.
Source
Thrown at packages/turbo-gen/src/utils/plop.ts:357
export async function runCustomGenerator({
project,
generator,
bypassArgs,
configPath
}: {
project: Project;
generator: Generator;
bypassArgs?: Array<string>;
configPath?: string;
}): Promise<void> {
const resolvedConfigPath = configPath ?? generator.configPath;
const destBasePath = configPath ?? generator.destBasePath;
const plop = await createPlopFromConfig(resolvedConfigPath, destBasePath);
if (!plop) {
throw new GeneratorError("Unable to load generators", {
type: "plop_unable_to_load_config"
});
}
let gen: PlopGenerator | undefined;
try {
gen = plop.getGenerator(generator.name) as PlopGenerator | undefined;
} catch {
// plop throws when generator not found
}
if (!gen) {
throw new GeneratorError(
`Generator ${qualifiedName(generator)} not found`,
{ type: "plop_generator_not_found" }
);
}
View on GitHub (pinned to f9245100cf)
Solutions
- Look at the error line logged just above; it is the real load failure from node-plop or esbuild
- Make the config export a function: module.exports = function (plop) { ... }
- Match the file extension to your package type: use .cjs when "type": "module" is set
- Ensure every import in the config resolves from the project
Example fix
// before: config exports an object
module.exports = { generators: [] };
// after: config exports a function that registers generators
module.exports = function (plop) {
plop.setGenerator("hello", {
prompts: [],
actions: [{ type: "add", path: "hello.txt", template: "hi" }]
});
}; Defensive patterns
Strategy: try-catch
Validate before calling
// smoke-load the config the same way turbo-gen does before running generators
import nodePlop from "node-plop";
const plop = await nodePlop(configPath, { destBasePath: root, force: false });
if (!plop) throw new Error("Unable to load generators"); Type guard
import type { NodePlopAPI } from "node-plop";
function isPlopInstance(value: unknown): value is NodePlopAPI {
return typeof value === "object" && value !== null && typeof (value as NodePlopAPI).getGenerator === "function";
} Try / catch
try {
await runPlopGenerator(args);
} catch (err) {
if (err instanceof GeneratorError && err.type === "plop_unable_to_load_config") {
// the real load error was logged above; fix the config export and retry
console.error("Config failed to load. Ensure it exports a function: module.exports = (plop) => {...}");
process.exitCode = 1;
} else {
throw err;
}
} Prevention
- Always export a function from plop configs, not an object
- Match config file extension to your package module type
- Load-test generator configs in CI with node-plop directly
When it happens
Trigger: The config file exists but does not work as a plop config: it does not export a function that receives plop, it throws during evaluation, or it imports something that fails to resolve. nodePlop() rejects, the catch returns undefined, and the caller converts that to this GeneratorError.
Common situations: module.exports = { ... } instead of module.exports = (plop) => { ... }. A plopfile written as ESM default export but loaded as CJS, or the reverse. A syntax error or missing dependency inside the config. TypeScript types stripped incorrectly during bundling.
Related errors
- plop_no_config
- plop_error_running_generator
- plop_generator_not_found
- plop_error_running_generator
- May not specify workspace name in non-root turbo.json
AI-assisted analysis of vercel/turborepo@f9245100cf (2026-08-17).
Data as JSON: /api/errors/72c0a32f867d770c.
Report an issue: GitHub.