withastro/astro · error · AstroError
CannotOptimizeSvg
CannotOptimizeSvg
Error message
An error occurred while optimizing SVG file "${path}" with the "${name}" optimizer. What it means
When Astro's SVG pipeline runs a configured optimizer (e.g. SVGO) over an SVG's contents and the optimizer throws, Astro wraps the failure as CannotOptimizeSvg with the original error attached as `cause` and includes the file path and optimizer name. The underlying optimizer error is the real problem; this error is the wrapper.
Solutions
- Inspect `error.cause` for the real optimizer message and fix the SVG at the reported location
- Validate/pretty-print the SVG first (e.g. open in a browser, or run an XML linter) to confirm it is well-formed
- Update or simplify the optimizer configuration: align svgo plugin names with your installed svgo major version, or remove the failing plugin
Example fix
// before (astro.config.mjs) — plugin API mismatch
svg: { optimizers: [{ name: 'svgo', options: { plugins: ['removeViewBox'] } }] }
// after
svg: { optimizers: [{ name: 'svgo', options: { plugins: [{ name: 'preset-default' }] } }] } Defensive patterns
Strategy: try-catch
Validate before calling
// smoke-test the optimizer config once in CI against real assets
import { optimize } from 'svgo';
for (const svg of await glob('src/assets/**/*.svg')) {
optimize(await readFile(svg, 'utf8')); // throws early if config/plugins are bad
}
console.log('svg optimizer ok'); Try / catch
try {
const node = await parseSvg({ path, contents, svgOptimizer });
} catch (err) {
if (err instanceof AstroError && err.code === 'CannotOptimizeSvg') {
console.error(`optimizer ${err.cause} failed on ${path}:`, err.cause);
// retry without the optimizer, or skip optimizing this file
return parseSvg({ path, contents });
}
throw err;
} Prevention
- Keep svgo plugin config aligned with the installed svgo major version
- Run the optimizer over the whole asset folder in CI so bad SVGs fail before deploy
- Always inspect error.cause — the wrapper message alone has no detail
When it happens
Trigger: Passing malformed SVG content through the SVG component/pipeline with an `svgOptimizer` configured; an SVGO plugin that chokes on the file (broken path data, invalid attributes, encoding issues); version drift between svgo v3 and v4 plugin APIs.
Common situations: Hand-edited SVGs with XML errors; SVGs exported from design tools containing unusual namespaces; adding a custom `svgoPlugins` config where a plugin name/API no longer matches the installed svgo major version.
Related errors
- ⚠️ Astro could not optimize image
- ⚠️ Astro expected an SVG for
- SVG file does not contain an
- UnsupportedImageConversion
- UnsupportedImageFormat
AI-assisted analysis of withastro/astro@157c500c38 (2026-08-27).
Data as JSON: /api/errors/6645f87dff0c9726.
Report an issue: GitHub.
Appendix: source
Thrown at packages/astro/src/assets/svg/utils.ts:22
import { dropAttributes } from '../runtime.js';
import type { ImageMetadata } from '../types.js';
import type { SvgOptimizer } from './types.js';
async function parseSvg({
path,
contents,
svgOptimizer,
}: {
path: string;
contents: string;
svgOptimizer: SvgOptimizer | undefined;
}) {
let processedContents = contents;
if (svgOptimizer) {
try {
processedContents = await svgOptimizer.optimize(contents, path);
} catch (cause) {
throw new AstroError(
{
...AstroErrorData.CannotOptimizeSvg,
message: AstroErrorData.CannotOptimizeSvg.message(path, svgOptimizer.name),
},
{ cause },
);
}
}
const root = parse(processedContents);
const svgNode = root.children.find(
({ name, type }: { name: string; type: number }) => type === ELEMENT_NODE && name === 'svg',
);
if (!svgNode) {
throw new Error('SVG file does not contain an <svg> element');
}
const { attributes, children } = svgNode;
const body = renderSync({ ...root, children });
View on GitHub (pinned to 157c500c38)