{"record":{"id":"2211ad10227c0c4f","repo":"jackwener/OpenCLI","slug":"label-returned-no-items","errorCode":null,"errorMessage":"${label} returned no items.","messagePattern":"(.+?) returned no items\\.","errorType":"exception","errorClass":"EmptyResultError","httpStatus":null,"severity":"warning","filePath":"clis/stackoverflow/utils.js","lineNumber":97,"sourceCode":"            'Inspect the URL in a browser for the canonical error context.',\n        );\n    }\n    return data;\n}\n\n/** Convert SE epoch seconds to YYYY-MM-DD. */\nexport function epochToDate(value) {\n    if (value == null || value === '') return '';\n    const n = Number(value);\n    if (!Number.isFinite(n) || n <= 0) return '';\n    return new Date(n * 1000).toISOString().slice(0, 10);\n}\n\n/** Throw EmptyResultError when an /items array is empty. */\nexport function ensureItems(data, label) {\n    const items = Array.isArray(data?.items) ? data.items : [];\n    if (items.length === 0) {\n        throw new EmptyResultError(label, `${label} returned no items.`);\n    }\n    return items;\n}\n\nconst HTML_ENTITY_MAP = {\n    '&amp;': '&', '&lt;': '<', '&gt;': '>', '&quot;': '\"',\n    '&#39;': \"'\", '&apos;': \"'\", '&nbsp;': ' ',\n};\n\n/**\n * Decode the small set of HTML entities Stack Exchange emits in display\n * names and titles (e.g. \"Jon Skeet&#39;s mentor\"). Decimal/hex numeric\n * refs are also handled.\n */\nexport function decodeHtmlEntities(value) {\n    if (value == null) return '';\n    return String(value)\n        .replace(/&#x([0-9a-fA-F]+);/g, (_, h) => String.fromCodePoint(parseInt(h, 16)))","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/stackoverflow/utils.js#L79-L115","documentation":"ensureItems validates that a Stack Exchange response contains a non-empty items array and throws EmptyResultError otherwise. It is a deliberate empty-result signal, not a failure of the request itself.","triggerScenarios":"Search/query matched nothing: e.g. search with a term that has no matches, user/reputation lookups for a nonexistent id, or filters that exclude all results.","commonSituations":"Misspelled search terms or usernames, querying a wrong site where the item does not exist, deleted/closed questions no longer returned by the API.","solutions":["Loosen the search term or remove filters and retry","Confirm the target entity exists on the site queried (correct site, correct id)","Handle EmptyResultError in the caller as an expected empty state","Check that the site parameter matches where the content actually lives"],"exampleFix":"// before\nconst data = await seFetch(url);\nconst items = ensureItems(data, 'stack exchange search');\n// after\nlet items;\ntry {\n  items = ensureItems(data, 'stack exchange search');\n} catch (e) {\n  if (e instanceof EmptyResultError) items = [];\n  else throw e;\n}","handlingStrategy":"validation","validationCode":"const data = await seFetch(url);\nif (!Array.isArray(data?.items) || data.items.length === 0) {\n  // treat as empty result up front\n}","typeGuard":"function hasItems(d) {\n  return Array.isArray(d?.items) && d.items.length > 0;\n}","tryCatchPattern":"try {\n  const items = ensureItems(data, 'search');\n} catch (e) {\n  if (e instanceof EmptyResultError) return []; // expected empty\n  throw e;\n}","preventionTips":["Check the query for typos before calling","Confirm the entity exists on the queried site","Treat EmptyResultError as an expected empty state, not a crash","Test with a known-good query to separate input problems from API problems"],"tags":["empty-result","api","validation"],"backgroundTag":"empty-result-set","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}