jackwener/OpenCLI · error · CommandExecutionError

${commandLabel} omitted summaries for one or more PMIDs

Error message

${commandLabel} omitted summaries for one or more PMIDs

What it means

After mapping PMIDs to summary rows, ensureCompleteSummaryRows checks for null rows (PMIDs with no matching entry in `result.result`) and throws `${commandLabel} omitted summaries for one or more PMIDs` with detail 'Refusing to return a partial result set.' The library throws this rather than silently returning incomplete metadata.

Source

Thrown at clis/pubmed/utils.js:243

        article_type: articleTypeFromList(article?.pubtype),
        doi: extractDoi(article?.articleids),
        url: buildPubMedUrl(id),
    };
}

export function ensureCompleteSummaryRows(pmids, result, commandLabel) {
    if (!result || typeof result !== 'object' || !result.result || typeof result.result !== 'object') {
        throw new CommandExecutionError(`${commandLabel} returned an unreadable summary payload`);
    }
    const rows = pmids.map((pmid, index) => {
        const article = result.result[pmid];
        if (!article) {
            return null;
        }
        return summaryToRow(article, index + 1, pmid);
    });
    if (rows.some(row => row === null)) {
        throw new CommandExecutionError(`${commandLabel} omitted summaries for one or more PMIDs`, 'Refusing to return a partial result set.');
    }
    return rows;
}

export function buildSearchQuery(query, filters = {}) {
    const terms = [requireText(query, 'query')];
    if (filters.author) terms.push(`${requireText(filters.author, 'author')}[Author]`);
    if (filters.journal) terms.push(`${requireText(filters.journal, 'journal')}[Journal]`);
    if (filters.yearFrom || filters.yearTo) {
        const from = filters.yearFrom || 1800;
        const to = filters.yearTo || new Date().getFullYear();
        if (from > to) {
            throw new ArgumentError('pubmed year-from must be <= year-to');
        }
        terms.push(`${from}:${to}[PDAT]`);
    }
    if (filters.articleType) terms.push(`${requireText(filters.articleType, 'article-type')}[PT]`);
    if (filters.hasAbstract) terms.push('hasabstract[text]');

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Validate each PMID before calling (numeric, correct length) and drop invalid ones
  2. Split the batch and query PMIDs individually to identify the offending one
  3. Handle the error by filtering the failing PMID and retrying the rest
  4. Confirm the PMID still exists on pubmed.ncbi.nlm.nih.gov/<pmid>/

Example fix

// before
const rows = await result(['12345678', '99999999999']); // throws
// after
const valid = ['12345678', '99999999999'].filter(p => /^\d{1,9}$/.test(p));
const rows = await result(valid);
Defensive patterns

Strategy: validation

Validate before calling

// Validate PMIDs before batching
function validPmids(list) {
  return list.filter(p => /^\d{1,9}$/.test(String(p)));
}
const pmids = validPmids(userPmids); // drop obviously invalid ones first

Type guard

function isPlausiblePmid(p) {
  return typeof p === 'string' || typeof p === 'number'
    ? /^\d{1,9}$/.test(String(p)) : false;
}

Try / catch

try {
  const rows = await result(pmids);
} catch (e) {
  if (/omitted summaries/.test(e.message)) {
    // fall back to per-PMID requests to isolate the bad record
    const all = await Promise.allSettled(pmids.map(p => result([p])));
    return all.filter(r => r.status === 'fulfilled').map(r => r.value[0]);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling fetchSummaryRows with at least one PMID for which NCBI's ESummary returns no entry — e.g. an invalid/withdrawn/deleted PMID mixed into an otherwise valid batch, or an out-of-range PMID.

Common situations: User-supplied PMID lists containing typos or deleted records; PMIDs from a stale saved list; batching PMIDs where one was retracted and removed from ESummary.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/20194387f435b6c2. Report an issue: GitHub.