parcel-bundler/parcel · error · ThrowableDiagnostic

[dynamic diagnostic from SVG transform errors]

Error message

[dynamic diagnostic from SVG transform errors]

What it means

Thrown by @parcel/transformer-svg when the underlying Rust transformSvg pass (via @parcel/rust) returns a non-empty errors array. The Rust core parses the SVG as XML and resolves references (e.g. <image href>, <use href>, <script xlink:href>); any parse failure or unresolvable reference is surfaced verbatim as a ThrowableDiagnostic. Because the message is dynamic, the actual text comes from the Rust diagnostics and may mention malformed XML, invalid attributes, or missing referenced files.

Source

Thrown at packages/transformers/svg/src/SVGTransformer.js:25

  envToRust,
  dependencyFromRust,
  assetFromRust,
} from '@parcel/rust';

export default (new Transformer({
  async transform({asset}) {
    asset.bundleBehavior = 'isolated';

    let res = transformSvg({
      code: await asset.getBuffer(),
      filePath: asset.filePath,
      xml: true,
      env: envToRust(asset.env),
      hmr: false,
    });

    if (res.errors.length) {
      throw new ThrowableDiagnostic({
        diagnostic: res.errors,
      });
    }

    asset.setBuffer(res.code);

    let assets = [asset];
    for (let dep of res.dependencies) {
      asset.addDependency(dependencyFromRust(dep));
    }

    for (let a of res.assets) {
      assets.push(assetFromRust(a));
    }

    return assets;
  },
}): Transformer);

View on GitHub (pinned to 59484858a1)

Solutions

  1. Open the SVG in a validator or editor with XML linting and fix the exact line/column cited in the surfaced diagnostic.
  2. Check every href/xlink:href in the file and confirm the referenced file exists relative to the SVG.
  3. If the error names a namespace, declare it on the root <svg> element or strip the offending attribute.
  4. Re-export the SVG from its design tool to regenerate clean XML.

Example fix

// before
<svg><use href="#missing"/></svg>
// after
<svg xmlns="http://www.w3.org/2000/svg"><defs><g id="missing"/></defs><use href="#missing"/></svg>
Defensive patterns

Strategy: validation

Validate before calling

const buf = await asset.getBuffer();
const text = buf.toString('utf8');
// cheap well-formedness pre-check: balanced root tag and parseable by DOMParser
const doc = new DOMParser().parseFromString(text, 'image/svg+xml');
if (doc.querySelector('parsererror')) {
  throw new Error('SVG is not well-formed XML; refusing to transform');
}
// also verify every href resolves
for (const el of doc.querySelectorAll('[href],[xlink\\:href]')) {
  const ref = el.getAttribute('href') || el.getAttributeNS('http://www.w3.org/1999/xlink', 'href');
  if (ref && !ref.startsWith('#') && !(await fs.exists(path.join(assetDir, ref)))) {
    throw new Error('Missing SVG reference: ' + ref);
  }
}

Type guard

function isWellFormedSvg(text) {
  const doc = new DOMParser().parseFromString(text, 'image/svg+xml');
  return !doc.querySelector('parsererror') && doc.documentElement.nodeName === 'svg';
}

Try / catch

try {
  await transformer.transform({asset});
} catch (e) {
  if (e?.diagnostics?.some(d => /svg|xml/i.test(d.message))) {
    console.warn('SVG transform failed; check XML well-formedness and href references');
  }
  throw e;
}

Prevention

When it happens

Trigger: An SVG asset is transformed (asset.getBuffer() fed to transformSvg with xml:true) and res.errors has length > 0. This happens on non-well-formed XML, undeclared namespaces, or when an href/xlink:href inside the SVG points at a path Parcel cannot resolve.

Common situations: Hand-edited SVG with a missing closing tag, a <use href="#id"> referencing an undefined fragment, an <image href="./missing.png">, copy-pasted SVG carrying an unsupported namespace, or a file accidentally saved as SVGZ/binary.

Related errors


AI-assisted analysis of parcel-bundler/parcel@59484858a1 (2026-08-13). Data as JSON: /api/errors/4e9638030cc7f628. Report an issue: GitHub.