jackwener/OpenCLI · info · EmptyResultError
${label} returned 404 (no matches).
Error message
${label} returned 404 (no matches). What it means
openFDA signals 'no matches found' by returning HTTP 404 rather than an empty results array. openfdaFetch translates that 404 into an EmptyResultError with this message so callers can treat it as a normal empty outcome instead of a transport error. The label names the originating openfda command.
Source
Thrown at clis/openfda/utils.js:35
export function requireBoundedInt(value, def, max, name = 'limit') {
const n = value == null || value === '' ? def : Number(value);
if (!Number.isInteger(n) || n < 1 || n > max) {
throw new ArgumentError(`--${name} must be an integer between 1 and ${max}`);
}
return n;
}
export async function openfdaFetch(url, label) {
let resp;
try {
resp = await fetch(url, { headers: { 'User-Agent': UA, accept: 'application/json' } });
} catch (err) {
throw new CommandExecutionError(`${label} request failed: ${err.message}`);
}
if (resp.status === 404) {
// openFDA returns 404 for "no matches" instead of an empty results array.
throw new EmptyResultError(label, `${label} returned 404 (no matches).`);
}
if (resp.status === 429) {
throw new CommandExecutionError(`${label} rate-limited (HTTP 429); back off and retry.`);
}
if (!resp.ok) {
throw new CommandExecutionError(`${label} returned HTTP ${resp.status}.`);
}
let body;
try {
body = await resp.json();
} catch (err) {
throw new CommandExecutionError(`${label} returned non-JSON body: ${err.message}`);
}
return body;
}
// openFDA returns most string fields as `[string]` arrays — collapse to first
// element. Preserves `null` (not coerced to empty string) when the slot isView on GitHub (pinned to 49907e53dc)
Solutions
- Broaden or correct the search term / filters and retry.
- Validate terms against openFDA's own search UI (open.fda.gov) before scripting them.
- Catch EmptyResultError in calling code and render 'no results' instead of failing.
- If 404 appears for a URL that should match, verify the endpoint path and query encoding (use +AND+ between clauses).
Example fix
// before
const rows = await fetchFoodRecalls({ q: 'Xyzzysnacks' }); // throws EmptyResultError
// after
try {
const rows = await fetchFoodRecalls({ q: 'Xyzzysnacks' });
} catch (e) {
if (e instanceof EmptyResultError) return []; // treat as empty
throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
function validateRecallQuery({ q }) {
if (q != null && q.trim().length < 2) throw new Error('search term too short');
return true;
} Type guard
function isEmptyResult(e) {
return e instanceof Error && e.name === 'EmptyResultError';
} Try / catch
try {
const rows = await fetchFoodRecalls(filter);
} catch (e) {
if (e instanceof EmptyResultError || /404 \(no matches\)/.test(e.message)) {
return []; // openFDA 404 == zero matches, not a failure
}
throw e;
} Prevention
- Always catch EmptyResultError around openfda calls — 404 means 'no matches'.
- Verify search terms against open.fda.gov interactively first.
- Prefer broader filters, then narrow down.
- Encode multi-clause searches with +AND+ / +OR+ correctly.
When it happens
Trigger: Any openfda query whose search term(s) match zero records — misspelled drug name, recall filters that never co-occur, an NDC/product string absent from the database. openfdaFetch converts the 404 status before the general !resp.ok branch runs.
Common situations: Searching a drug that only exists under another spelling; querying enforcement records for a state/date combo with no recalls; automations that assume every query has results and crash on the empty case.
Related errors
- openFDA returned no labels matching "${query}".
- openFDA returned no food recall records matching the filter.
- Semantic Scholar returned 404 for ${url}.
- Homebrew API returned 404 for ${url}.
- No posts found for "${keyword}"
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/35e7de31a4a5c76f.
Report an issue: GitHub.