{"record":{"id":"d48b643b4e9e948d","repo":"jackwener/OpenCLI","slug":"label-returned-an-error","errorCode":null,"errorMessage":"${label} returned an error","messagePattern":"(.+?) returned an error","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/pubmed/utils.js","lineNumber":130,"sourceCode":"        const json = await response.json();\n        assertNoEutilsError(json, label);\n        return json;\n    }\n    catch (error) {\n        if (error instanceof CommandExecutionError) {\n            throw error;\n        }\n        const detail = error instanceof Error ? error.message : String(error);\n        throw new CommandExecutionError(`${label} returned invalid JSON`, detail);\n    }\n}\n\nexport function assertNoEutilsError(json, label = 'PubMed E-utilities') {\n    const error = json?.error\n        || json?.esearchresult?.errorlist?.phrasesnotfound?.join(', ')\n        || json?.esearchresult?.errorlist?.fieldsnotfound?.join(', ');\n    if (error) {\n        throw new CommandExecutionError(`${label} returned an error`, String(error));\n    }\n}\n\nexport function buildPubMedUrl(pmid) {\n    return `https://pubmed.ncbi.nlm.nih.gov/${pmid}/`;\n}\n\nexport function decodeXmlEntities(value) {\n    return String(value ?? '')\n        .replace(/&amp;/g, '&')\n        .replace(/&lt;/g, '<')\n        .replace(/&gt;/g, '>')\n        .replace(/&quot;/g, '\"')\n        .replace(/&apos;/g, \"'\")\n        .replace(/&#39;/g, \"'\")\n        .replace(/&#x([0-9a-f]+);/gi, (_, hex) => String.fromCodePoint(Number.parseInt(hex, 16)))\n        .replace(/&#(\\d+);/g, (_, dec) => String.fromCodePoint(Number.parseInt(dec, 10)));\n}","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/pubmed/utils.js#L112-L148","documentation":"assertNoEutilsError inspects a parsed E-utilities JSON payload for NCBI's error shapes: a top-level `error` field or `esearchresult.errorlist.phrasesnotfound` / `fieldsnotfound`. If any is present it throws `${label} returned an error` with the joined messages as detail. The library throws this to surface semantic API errors that still arrive with HTTP 200.","triggerScenarios":"Calling esearch (via eutilsFetch) when NCBI rejects the query: an unrecognized search field, a query phrase that matches nothing (phrasesnotfound), an invalid field name, or an API-level error object in the JSON body.","commonSituations":"Typos in PubMed field tags like [Authr] instead of [Author]; quoted phrases with zero matches; malformed query syntax passed by the user; NCBI deprecating a search field.","solutions":["Read the `detail` on the error — it contains the exact NCBI message (e.g. which phrase or field was not found)","Fix the query syntax or field tags in the search term","Remove or simplify quoted phrases that match no documents","Test the same query manually on pubmed.ncbi.nlm.nih.gov to validate syntax"],"exampleFix":"// before\nconst rows = await searchQuery('Smith J[Authr]'); // typo\n// after\nconst rows = await searchQuery('Smith J[Author]');","handlingStrategy":"try-catch","validationCode":"// Pre-validate query field tags and quoted phrases\nfunction validateQuery(q) {\n  const badTag = /\\[(?!Author|Journal|Title|Abstract|PDAT|PT|Affiliation)[^\\]]+\\]/i.exec(q);\n  if (badTag) throw new Error(`Suspicious field tag: ${badTag[0]}`);\n}","typeGuard":"function isEutilsError(json) {\n  return Boolean(json?.error\n    || json?.esearchresult?.errorlist?.phrasesnotfound?.length\n    || json?.esearchresult?.errorlist?.fieldsnotfound?.length);\n}","tryCatchPattern":"try {\n  const json = await esearch(query);\n} catch (e) {\n  if (/returned an error/.test(e.message)) {\n    console.error('NCBI says:', e.detail); // fix query per detail\n  }\n  throw e;\n}","preventionTips":["Validate PubMed field tags against the current E-utilities field list","Test queries manually on the PubMed website before automating","Avoid quoted phrases that may match zero documents; log e.detail for the exact message","Keep queries simple and build them with the library's buildSearchQuery filters"],"tags":["pubmed","eutils","api-error","query-validation"],"backgroundTag":"api-error-response","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}