jackwener/OpenCLI · error · CommandExecutionError
pubmed article response did not include a PMID
Error message
pubmed article response did not include a PMID
What it means
parseArticleXml extracts the PMID from the EFetch XML response and throws 'pubmed article response did not include a PMID' when no <PMID> element can be found, even though the body looked like a PubmedArticle. The library throws this because without the returned PMID it cannot verify the response corresponds to the requested article.
Source
Thrown at clis/pubmed/utils.js:275
}
terms.push(`${from}:${to}[PDAT]`);
}
if (filters.articleType) terms.push(`${requireText(filters.articleType, 'article-type')}[PT]`);
if (filters.hasAbstract) terms.push('hasabstract[text]');
if (filters.hasFullText) terms.push('free full text[sb]');
if (filters.humanOnly) terms.push('humans[mesh]');
if (filters.englishOnly) terms.push('english[lang]');
return terms.join(' AND ');
}
export function parseArticleXml(xml, pmid) {
const text = String(xml ?? '');
if (!text || /<ERROR\b/i.test(text) || !/<PubmedArticle\b/i.test(text)) {
return null;
}
const returnedPmid = extractFirst(text, 'PMID');
if (!returnedPmid) {
throw new CommandExecutionError('pubmed article response did not include a PMID', 'PubMed EFetch response shape may have changed.');
}
if (returnedPmid !== pmid) {
throw new CommandExecutionError(`pubmed article response PMID ${returnedPmid} did not match requested PMID ${pmid}`, 'Refusing to return metadata for a different article.');
}
const articleBlock = text.match(/<Article\b[^>]*>([\s\S]*?)<\/Article>/i)?.[1] || text;
const journalBlock = articleBlock.match(/<Journal\b[^>]*>([\s\S]*?)<\/Journal>/i)?.[1] || '';
const journalIssue = journalBlock.match(/<JournalIssue\b[^>]*>([\s\S]*?)<\/JournalIssue>/i)?.[1] || '';
const pubDate = journalIssue.match(/<PubDate\b[^>]*>([\s\S]*?)<\/PubDate>/i)?.[1] || '';
const authorBlocks = [...text.matchAll(/<Author\b[^>]*>([\s\S]*?)<\/Author>/gi)].map(match => match[1]);
const authors = authorBlocks.map(block => {
const name = extractFirst(block, 'CollectiveName') || [extractFirst(block, 'LastName'), extractFirst(block, 'ForeName') || extractFirst(block, 'Initials')].filter(Boolean).join(' ');
return name;
}).filter(Boolean);
const abstract = extractAll(articleBlock, 'AbstractText').join(' ');
const pubTypes = extractAll(articleBlock, 'PublicationType');
const meshTerms = extractAll(text, 'DescriptorName');
const keywords = extractAll(text, 'Keyword');
const affiliations = extractAll(text, 'Affiliation');View on GitHub (pinned to 49907e53dc)
Solutions
- Retry the request — a transient truncation can drop elements
- Inspect the raw XML to confirm whether <PMID> is genuinely absent
- Check for NCBI DTD/schema updates and update the parser if tags changed
- Fall back to fetching metadata from the PubMed web page instead of EFetch
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-flight: confirm the article exists before parsing
const res = await fetch(`https://pubmed.ncbi.nlm.nih.gov/${pmid}/`);
if (!res.ok) throw new Error(`PMID ${pmid} not found on PubMed`); Type guard
function hasPmidElement(xmlText) {
return /<PMID\b[^>]*>[^<]+<\/PMID>/i.test(String(xmlText));
} Try / catch
try {
const meta = await article(pmid);
} catch (e) {
if (/did not include a PMID/.test(e.message)) {
console.error('EFetch XML had no <PMID>; inspect raw response:', e.detail);
}
throw e;
} Prevention
- Log raw EFetch XML on failure to detect schema/truncation issues
- Pin and monitor NCBI DTD/schema versions for changes
- Retry once on parse failures — truncation can be transient
- Keep a fallback path (PubMed web scrape / other API) for metadata
When it happens
Trigger: Calling the article command when NCBI's EFetch returns a PubmedArticle-shaped document with no <PMID> tag inside — typically due to an NCBI response format change, a heavily truncated/garbled XML body, or XML where the PMID tag is namespaced/renamed.
Common situations: NCBI schema updates altering tag placement; proxies mangling XML; NCBI returning an unusual article encoding (e.g. PMC-sourced records without PMID).
Related errors
- ${commandLabel} returned an unreadable summary payload
- pubmed article response PMID ${returnedPmid} did not match r
- Boss friend list response did not include zpData.friendList
- dianping search parser found result cards without shop_id va
- ${command} returned a malformed rows payload
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/bfbef0889b9e01dc.
Report an issue: GitHub.