{"record":{"id":"76c797911bff4bb7","repo":"jackwener/OpenCLI","slug":"pubmed-search-did-not-return-an-id-list","errorCode":null,"errorMessage":"pubmed search did not return an id list","messagePattern":"pubmed search did not return an id list","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/pubmed/search.js","lineNumber":68,"sourceCode":"            author: args.author,\n            journal: args.journal,\n            yearFrom,\n            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":50,"sourceCodeEnd":76,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/pubmed/search.js#L50-L76","documentation":"This CommandExecutionError is thrown when the ESearch response for the core `pubmed search` command does not include a valid `esearchresult.idlist` array. The library treats the ESearch contract (idlist always present, even if empty) as mandatory; deviation means the request effectively failed or the API changed.","triggerScenarios":"PubMed returns an esearchresult containing an ERROR entry (bad query syntax like unbalanced quotes/field tags), rate-limit or HTML error bodies, eutilsFetch returning null/undefined, or an upstream schema change.","commonSituations":"Exceeding 3 anonymous requests/second to E-utilities; invalid query syntax (e.g. `author[Auther]`, stray quotes) causing an API-side error object; NCBI outage; aggressive retry loops getting throttled.","solutions":["Retry after a short backoff — rate limiting and transient errors are the most common cause","Validate the query syntax (balanced quotes, correct field tags like [Author], [MeSH])","Register an NCBI api_key and throttle requests to <=3/sec","Log the raw esearch response to see the actual body and update the parser if NCBI changed the schema"],"exampleFix":"// before\nclis.pubmedSearch({ query: '\"machine learning AND [Title' });\n// after\nclis.pubmedSearch({ query: '\"machine learning\"[Title]' });","handlingStrategy":"retry","validationCode":"// Basic query sanity before hitting the API\nfunction assertValidPubMedQuery(q) {\n  const s = String(q);\n  const quotes = (s.match(/\"/g) || []).length;\n  if (quotes % 2 !== 0) throw new Error('unbalanced quotes in query');\n  if (/\\[(?!\\w+\\])/.test(s)) console.warn('possible malformed field tag in query');\n}","typeGuard":"function hasIdlist(res) {\n  return Array.isArray(res?.esearchresult?.idlist);\n}","tryCatchPattern":"try {\n  return await clis.pubmedSearch({ query, limit });\n} catch (e) {\n  if (e.name === 'CommandExecutionError' && /did not return an id list/.test(e.message)) {\n    if (attempt < 3) { await sleep(2 ** attempt * 500); return retry(attempt + 1); }\n  }\n  throw e; // persistent failures: inspect raw body / schema\n}","preventionTips":["Use exponential backoff with jitter and an api_key to stay under 3 req/sec","Validate query syntax (quotes, [Field] tags) client-side before sending","Log the raw esearch body on failure to distinguish rate limits from schema drift","Cap retry attempts and surface the underlying cause rather than looping endlessly"],"tags":["network","api-response","pubmed","schema-change"],"backgroundTag":"unexpected-api-response-shape","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}