{"record":{"id":"02e34837c7548e7e","repo":"jackwener/OpenCLI","slug":"pubmed-search","errorCode":null,"errorMessage":"pubmed search","messagePattern":"pubmed search","errorType":"exception","errorClass":"EmptyResultError","httpStatus":null,"severity":"error","filePath":"clis/pubmed/search.js","lineNumber":71,"sourceCode":"            yearTo,\n            articleType: args['article-type'],\n            hasAbstract: args['has-abstract'],\n            hasFullText: args['free-full-text'],\n            humanOnly: args['humans-only'],\n            englishOnly: args['english-only'],\n        });\n        const esearch = await eutilsFetch('esearch', {\n            term: searchQuery,\n            retmax: limit,\n            usehistory: 'y',\n            sort: sortMap[sort],\n        }, { label: 'pubmed search' });\n        const pmids = esearch?.esearchresult?.idlist;\n        if (!Array.isArray(pmids)) {\n            throw new CommandExecutionError('pubmed search did not return an id list', 'PubMed ESearch response shape may have changed.');\n        }\n        if (pmids.length === 0) {\n            throw new EmptyResultError('pubmed search', `No articles matched \"${query}\".`);\n        }\n        return fetchSummaryRows(pmids, 'pubmed search summary');\n    },\n});\n","sourceCodeStart":53,"sourceCodeEnd":76,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/pubmed/search.js#L53-L76","documentation":"Thrown by the 'pubmed search' command after the NCBI ESearch call. If the response lacks a valid esearchresult.idlist array it throws CommandExecutionError ('response shape may have changed'); if the id list is empty it throws EmptyResultError naming the query. It protects the downstream fetchSummaryRows step from undefined data.","triggerScenarios":"Running `pubmed search <query>` when NCBI returns an unexpected JSON body (schema change, error payload with HTTP 200, rate-limit HTML) or when the query matches zero articles.","commonSituations":"Overly specific queries returning nothing; NCBI E-utilities outages or throttling; proxies injecting error pages; E-utilities API changes after an NCBI update.","solutions":["Broaden or simplify the query and re-run (check quoting of boolean operators like AND/OR)","Re-run later if transient; verify NCBI availability with curl on the eutils endpoint","Inspect the raw ESearch JSON to see the actual response shape","Set NCBI_API_KEY to avoid rate-limit-induced error payloads","Update the pubmed CLI/library if the E-utilities schema changed"],"exampleFix":"// before\npubmed search '\"ultra rare [phrase' --limit 5\n// after\npubmed search 'CRISPR AND cattle' --limit 5","handlingStrategy":"try-catch","validationCode":"const res = await fetch(esearchUrl);\nconst body = await res.json();\nif (!Array.isArray(body?.esearchresult?.idlist)) {\n  throw new Error('unexpected ESearch shape: ' + JSON.stringify(body).slice(0, 200));\n}","typeGuard":"function hasIdList(r) {\n  return r != null && typeof r === 'object'\n    && r.esearchresult != null\n    && Array.isArray(r.esearchresult.idlist);\n}","tryCatchPattern":"try {\n  const pmids = await pubmedSearch(query);\n} catch (err) {\n  if (err instanceof EmptyResultError) {\n    console.warn(`no results for \"${query}\"`); // handle empty as normal case\n  } else if (err instanceof CommandExecutionError) {\n    console.error('PubMed ESearch failed:', err.detail);\n  } else { throw err; }\n}","preventionTips":["Treat empty results as an expected branch, not a crash","Validate the response shape before consuming nested fields","Broaden queries before assuming an API failure","Set NCBI_API_KEY to avoid throttling-related error payloads","Pin/update the CLI version when NCBI changes E-utilities schemas"],"tags":["pubmed","api-response-shape","empty-results","ncbi"],"backgroundTag":"unexpected-api-response-shape","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}