parcel-bundler/parcel · error · Error
Plugin ${pluginName} is not a valid Parcel plugin, should ex
Error message
Plugin ${pluginName} is not a valid Parcel plugin, should export an instance of a Parcel plugin ex. "export default new Reporter({ ... })". What it means
After unwrapping the default export, Parcel looks for the internal `CONFIG` symbol that marks an object as a genuine Parcel plugin instance (created via `new Reporter()`, `new Transformer()`, etc.). If the module exports a plain object/function/array instead, the `CONFIG` lookup returns falsy and Parcel reports that this is not a valid plugin, with an example of the correct shape.
Source
Thrown at packages/core/core/src/loadParcelPlugin.js:236
]),
},
],
},
});
}
}
}
let plugin = await options.packageManager.require(pluginName, resolveFrom, {
shouldAutoInstall: options.shouldAutoInstall,
});
plugin = plugin.default ? plugin.default : plugin;
if (!plugin) {
throw new Error(`Plugin ${pluginName} has no exports.`);
}
plugin = plugin[CONFIG];
if (!plugin) {
throw new Error(
`Plugin ${pluginName} is not a valid Parcel plugin, should export an instance of a Parcel plugin ex. "export default new Reporter({ ... })".`,
);
}
return {
plugin,
version: nullthrows(pkg).version,
resolveFrom: toProjectPath(options.projectRoot, resolveFrom),
range,
};
}
View on GitHub (pinned to 59484858a1)
Solutions
- Wrap the plugin definition in the appropriate class from `@parcel/plugin` (e.g. `new Reporter({...})`).
- Make sure the instance is the default export.
- If subclassing, ensure you call the base constructor so the `CONFIG` symbol is set.
Example fix
// before
export default { async transform({asset}) { return [asset]; } };
// after
import {Transformer} from '@parcel/plugin';
export default new Transformer({ async transform({asset}) { return [asset]; } }); Defensive patterns
Strategy: type-guard
Validate before calling
// Confirm the export is a Parcel plugin instance (has CONFIG).
const exp = mod.default ?? mod;
if (!exp || !exp[CONFIG]) {
throw new Error(`${name} is not a Parcel plugin instance`);
} Type guard
function isParcelPluginInstance(exp: any): boolean {
return Boolean(exp && exp[CONFIG]);
} Prevention
- Construct plugin instances with classes from @parcel/plugin.
- Don't return plain config objects as the default export.
- Add a unit test asserting `default[CONFIG]` exists.
When it happens
Trigger: A plugin module's default export is a plain config object, a class, or a function rather than an instance produced by a Parcel plugin class.
Common situations: Plugin author returns a raw object literal `export default { transform() {...} }` instead of wrapping it in `new Transformer({...})`.
Related errors
- Plugin ${pluginName} has no exports.
- Bundle is not inline and unable to retrieve contents
- Asset has an AST but no generate method is available on the
- ${pluginName} does not have a generate method
- Local plugins are not supported in Parcel config packages. P
AI-assisted analysis of parcel-bundler/parcel@59484858a1 (2026-08-13).
Data as JSON: /api/errors/bb8d0e81a757b1d0.
Report an issue: GitHub.