{"record":{"id":"0b2f131671c1b4f7","repo":"jackwener/OpenCLI","slug":"commandlabel-returned-an-unreadable-summary-pay","errorCode":null,"errorMessage":"${commandLabel} returned an unreadable summary payload","messagePattern":"(.+?) returned an unreadable summary payload","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/pubmed/utils.js","lineNumber":233,"sourceCode":"\nexport function summaryToRow(article, rank, pmid = article?.uid) {\n    const id = String(pmid ?? article?.uid ?? '').trim();\n    return {\n        rank,\n        pmid: id,\n        title: truncateText(String(article?.title ?? '').replace(/\\.$/, ''), 120),\n        authors: extractAuthors(article?.authors, 3),\n        journal: truncateText(article?.fulljournalname || article?.source || '', 60),\n        year: String(article?.pubdate ?? '').split(' ')[0] || '',\n        article_type: articleTypeFromList(article?.pubtype),\n        doi: extractDoi(article?.articleids),\n        url: buildPubMedUrl(id),\n    };\n}\n\nexport function ensureCompleteSummaryRows(pmids, result, commandLabel) {\n    if (!result || typeof result !== 'object' || !result.result || typeof result.result !== 'object') {\n        throw new CommandExecutionError(`${commandLabel} returned an unreadable summary payload`);\n    }\n    const rows = pmids.map((pmid, index) => {\n        const article = result.result[pmid];\n        if (!article) {\n            return null;\n        }\n        return summaryToRow(article, index + 1, pmid);\n    });\n    if (rows.some(row => row === null)) {\n        throw new CommandExecutionError(`${commandLabel} omitted summaries for one or more PMIDs`, 'Refusing to return a partial result set.');\n    }\n    return rows;\n}\n\nexport function buildSearchQuery(query, filters = {}) {\n    const terms = [requireText(query, 'query')];\n    if (filters.author) terms.push(`${requireText(filters.author, 'author')}[Author]`);\n    if (filters.journal) terms.push(`${requireText(filters.journal, 'journal')}[Journal]`);","sourceCodeStart":215,"sourceCodeEnd":251,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/pubmed/utils.js#L215-L251","documentation":"ensureCompleteSummaryRows validates the JSON returned by ESummary before mapping PMIDs to rows. If `result` is missing, not an object, or lacks an object-shaped `result.result`, it throws `${commandLabel} returned an unreadable summary payload`. The library throws this because it cannot safely extract per-PMID summaries from an unexpected response shape.","triggerScenarios":"Calling fetchSummaryRows (the result/esummary command) when NCBI returns an unexpected body for retmode=json — e.g. an error JSON without the usual `result` envelope, a redirect body, or an API format change.","commonSituations":"NCBI changing the ESummary JSON schema; a proxy returning a different payload; passing invalid web-env/params causing NCBI to return an error envelope instead of summaries; service outage mid-response.","solutions":["Log/inspect the raw response body to see what NCBI actually returned","Retry the request — transient NCBI issues can produce malformed bodies","Verify the PMIDs and esummary parameters are valid","Check whether NCBI changed the ESummary JSON schema and update the CLI if so"],"exampleFix":"// before\nconst rows = await result(pmids); // throws on unreadable payload\n// after\nlet rows;\ntry {\n  rows = await result(pmids);\n} catch (e) {\n  console.error('raw payload:', e.detail); // inspect what came back\n  throw e;\n}","handlingStrategy":"type-guard","validationCode":"// Validate the summary payload before mapping rows\nfunction isReadableSummary(json) {\n  return json && typeof json === 'object'\n    && json.result && typeof json.result === 'object';\n}","typeGuard":"function hasSummaryResult(json) {\n  return typeof json === 'object' && json !== null\n    && typeof json.result === 'object' && json.result !== null;\n}","tryCatchPattern":"try {\n  const rows = await result(pmids);\n} catch (e) {\n  if (/unreadable summary payload/.test(e.message)) {\n    console.error('payload detail:', e.detail);\n  }\n  throw e;\n}","preventionTips":["Check NCBI ESummary API docs for schema changes periodically","Log the raw response when this error occurs to spot format drift","Retry transient failures — a truncated body can look unreadable","Pin/monitor the CLI version against NCBI API changes"],"tags":["pubmed","eutils","schema-mismatch","response-shape"],"backgroundTag":"unexpected-response-schema","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}