badges/shields · error · InvalidResponse
${e.message}
Error message
${e.message} What it means
Thrown by the dynamic-xml service's transform when new DOMParser().parseFromString(buffer, contentType) throws, and the original exception's message is surfaced as an InvalidResponse. This means the fetched document could not be parsed as the given content type (XML/HTML) — typically malformed markup or a non-XML response. Note that XML parse errors may surface here or as values-less downstream failures depending on the parser implementation.
Source
Thrown at services/dynamic/dynamic-xml.service.js:89
}
static defaultBadgeData = { label: 'custom badge' }
getmimeType(contentType) {
return MIME_TYPES.find(mime => contentType.includes(mime)) ?? 'text/xml'
}
transform({ pathExpression, buffer, contentType = 'text/xml' }) {
// e.g. //book[2]/@id
const pathIsAttr = (
pathExpression.split('/').slice(-1)[0] || ''
).startsWith('@')
let parsed
try {
parsed = new DOMParser().parseFromString(buffer, contentType)
} catch (e) {
throw new InvalidResponse({ prettyMessage: e.message })
}
let values
try {
if (contentType === 'text/html') {
values = xpath
.parse(pathExpression)
.select({ node: parsed, isHtml: true })
} else {
values = xpath.select(pathExpression, parsed)
}
} catch (e) {
throw new InvalidParameter({ prettyMessage: e.message })
}
if (
typeof values === 'string' ||
typeof values === 'number' ||View on GitHub (pinned to 766fd8bc89)
Solutions
- Fetch the url and validate the document is well-formed XML/HTML (xmllint or an online validator).
- Ensure the contentType matches the actual response (use text/html for HTML documents).
- Check the upstream API status — an error page is often the real cause.
- Verify encoding/escaping of the url and response (UTF-8).
Example fix
// before url=https://api.example.com/data.json parsed as XML // after url=https://api.example.com/data.xml (or switch service to dynamic/json)
Defensive patterns
Strategy: validation
Validate before calling
function looksLikeXml(s) {
const t = s.trim();
return t.startsWith('<') && !t.startsWith('<!DOCTYPE html') && /<\/?[\w:-]+[\s\S]*/.test(t);
}
const body = await fetch(url).then(r => r.text());
if (!looksLikeXml(body)) throw new Error('url does not return XML'); Type guard
function isHtmlContentType(ct) { return /^text\/html/i.test(ct || ''); }
function isXmlLike(body) { return typeof body === 'string' && body.trim().startsWith('<?xml'); } Try / catch
try {
const value = await dynamicXml({ url, path, contentType });
} catch (err) {
// InvalidResponse wrapping parser error message — check the upstream response
console.error('XML parse failed:', err.message);
throw err;
} Prevention
- Validate upstream documents are well-formed XML (xmllint) before wiring a dynamic-xml badge.
- Match contentType to the actual response format (text/html for HTML docs).
- Monitor the upstream API — HTML error pages during outages cause parse failures.
When it happens
Trigger: The url returns content that fails DOM parsing with the declared contentType: truncated XML, HTML when XML parsing was selected, a JSON or plain-text error page, or an encoding problem that breaks the parser.
Common situations: API outage returning an HTML error page; wrong url pointing at JSON instead of XML; missing/incorrect Content-Type handling; CDATA/entity issues in the upstream document.
Related errors
AI-assisted analysis of badges/shields@766fd8bc89 (2026-08-30).
Data as JSON: /api/errors/dfdb60669933687f.
Report an issue: GitHub.