parcel-bundler/parcel · error · ThrowableDiagnostic
Unsupported custom SVGO plugin.
Error message
Unsupported custom SVGO plugin.
What it means
Thrown by @parcel/utils svgo plugin normalization when a Parcel/SVGO config supplies a custom SVGO plugin as a function (plugin.fn is a function, or the plugin entry itself is a function). Parcel only supports SVGO's built-in named plugins, not user-supplied JS function plugins, so it emits a diagnostic via throwDiagnostic with a code frame pointing at the offending config location.
Source
Thrown at packages/core/utils/src/svgo.js:136
typeof params === 'object' &&
typeof params?.overrides === 'object' &&
params.overrides
) {
for (let key in params.overrides) {
result[key] = params.overrides[key];
}
}
} else if (typeof name === 'string') {
result[(name: any)] = params || false;
}
}
}
return result;
}
async function throwDiagnostic(message, filePath, jsonPath, fs, hint) {
throw new ThrowableDiagnostic({
diagnostic: {
message: message,
codeFrames: [
{
filePath: filePath,
codeHighlights:
path.extname(filePath) === '' || path.extname(filePath) === '.json'
? generateJSONCodeHighlights(
await fs.readFile(filePath, 'utf8'),
[
{
key: jsonPath,
},
],
)
: [],
},
],View on GitHub (pinned to 59484858a1)
Solutions
- Replace function plugins with the equivalent built-in named SVGO plugin (e.g. 'removeViewBox', 'mergePaths') and configure via params.
- If you need custom transformation, pre-process the SVG with a separate tool/step before Parcel.
- Remove the offending plugin entry from the config file highlighted in the diagnostic.
- Consult SVGO's plugin list and map your custom function to the closest built-in.
Example fix
// before — .svgo.json or parcel svgo config
{
"plugins": [{ "name": "mine", "fn": () => ({}) }]
}
// after — use a built-in named plugin
{
"plugins": ["preset-default", "removeViewBox"]
} Defensive patterns
Strategy: validation
Validate before calling
// Reject function-based SVGO plugins before handing config to Parcel.
function assertNoFunctionPlugins(svgoConfig) {
const plugins = svgoConfig?.plugins ?? [];
for (const p of plugins) {
if (typeof p === 'function' || (p && typeof p.fn === 'function')) {
throw new Error('Parcel does not support custom function SVGO plugins; use named built-ins.');
}
}
} Type guard
type NamedPlugin = string | { name: string; params?: object };
function isNamedSVGOPlugin(p: unknown): p is NamedPlugin {
return typeof p === 'string' || (typeof p === 'object' && p !== null && typeof (p as any).name === 'string');
} Prevention
- Use only built-in named SVGO plugins in Parcel configs.
- Run custom SVG transforms in a pre-build step, not via SVGO plugin functions.
- Keep raw SVGO configs out of Parcel; convert to named-plugin form.
When it happens
Trigger: Authoring a .parcelrc or SVG optimizer config whose svgo.plugins array contains an inline function plugin (e.g. `plugins: [() => {...}]` or `plugins: [{name:'x', fn: () => ...}]`) instead of a named built-in plugin string or name+params object.
Common situations: Porting a raw SVGO config (which allows custom plugins) into Parcel; tutorials suggesting function-based SVGO plugins; upgrading SVGO version where the plugin shape changed.
Related errors
- Library targets are not supported in serve mode.
- Expected package.json file in ${rootDir}
- Unexpected output file type ${ext} in target "${targetName}"
- The "global" output format is not supported in the "${target
- Output format "esmodule" cannot be used in the "main" target
AI-assisted analysis of parcel-bundler/parcel@59484858a1 (2026-08-13).
Data as JSON: /api/errors/c4017e64937fbbf2.
Report an issue: GitHub.