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

  1. Inspect `error.cause` for the real optimizer message and fix the SVG at the reported location
  2. Validate/pretty-print the SVG first (e.g. open in a browser, or run an XML linter) to confirm it is well-formed
  3. 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

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


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)