jackwener/OpenCLI · error · CommandExecutionError
pubmed article response PMID ${returnedPmid} did not match r
Error message
pubmed article response PMID ${returnedPmid} did not match requested PMID ${pmid} What it means
parseArticleXml compares the PMID found in the EFetch XML against the requested PMID and throws `pubmed article response PMID ${returnedPmid} did not match requested PMID ${pmid}` on mismatch. This guards against returning metadata for a different article than the user asked for (detail: 'Refusing to return metadata for a different article.').
Source
Thrown at clis/pubmed/utils.js:278
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');
const grantBlocks = [...text.matchAll(/<Grant\b[^>]*>([\s\S]*?)<\/Grant>/gi)].map(match => match[1]);
const grants = grantBlocks.map(block => {
const grantId = extractFirst(block, 'GrantID');View on GitHub (pinned to 49907e53dc)
Solutions
- Verify the PMID on pubmed.ncbi.nlm.nih.gov/<pmid>/ — it may have been superseded
- Re-run with the canonical PMID PubMed reports after a merge
- Clear any caching layer between the CLI and NCBI and retry
- Double-check the PMID was not mistyped or swapped in your code
Example fix
// before
await article('31452104'); // cache returned PMIDs for 29868059
// after
cache.clear();
await article('31452104'); // or use the canonical PMID PubMed reports Defensive patterns
Strategy: validation
Validate before calling
// Confirm the canonical PMID before requesting metadata
const res = await fetch(`https://pubmed.ncbi.nlm.nih.gov/${pmid}/`);
const html = await res.text();
const canonical = /citation_\w*pmid\" content=\"(\d+)\"/.exec(html)?.[1];
if (canonical && canonical !== String(pmid)) {
pmid = canonical; // PMID was merged/replaced — use the canonical one
} Type guard
function pmidMatches(responseXml, requested) {
const m = /<PMID\b[^>]*>([^<]+)<\/PMID>/i.exec(String(responseXml));
return Boolean(m) && m[1].trim() === String(requested);
} Try / catch
try {
const meta = await article(pmid);
} catch (e) {
const m = /PMID (\d+) did not match requested PMID (\d+)/.exec(e.message);
if (m) return article(m[1]); // retry with the PMID the server actually returned
throw e;
} Prevention
- Resolve PMIDs through PubMed's canonical lookup; handle merged records
- Avoid caching EFetch responses keyed loosely — key strictly by PMID
- Double-check PMIDs for typos before requesting
- Log both requested and returned PMIDs when this error occurs
When it happens
Trigger: Calling the article command with a PMID when NCBI returns an article record for a different identifier — e.g. the PMID was merged/replaced and NCBI substituted the canonical record, or a caching/proxy layer returned a stale response for another PMID.
Common situations: PubMed PMID merges after journal changes; using a wrong or mistyped PMID that maps to another record; CDN or local cache serving the wrong response; requesting via a secondary ID (DOI/PMC) resolved to a different PMID.
Related errors
- ${commandLabel} omitted summaries for one or more PMIDs
- pubmed article response did not include a PMID
- Bilibili creator comparison returned a malformed manuscript
- Bilibili creator comparison returned duplicate rows for ${bv
- Bilibili view API returned duplicate page entries for p=${pa
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/9dd9cfebb380bec9.
Report an issue: GitHub.