jackwener/OpenCLI · warning · EmptyResultError
Homebrew API returned 404 for ${url}.
Error message
Homebrew API returned 404 for ${url}. What it means
brewFetch treats HTTP 404 from the Homebrew API specially: instead of a generic command error it throws EmptyResultError labeled with the request target, because a 404 from formulae.brew.sh means the formula/cask token (or analytics endpoint) does not exist rather than that something broke. The message includes the full URL for debugging.
Source
Thrown at clis/homebrew/utils.js:72
`Allowed: ${allowed.join(', ')}.`,
);
}
return s;
}
export async function brewFetch(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 ?? err}`,
'Check that formulae.brew.sh is reachable from this network.',
);
}
if (resp.status === 404) {
throw new EmptyResultError(label, `Homebrew API returned 404 for ${url}.`);
}
if (resp.status === 429) {
throw new CommandExecutionError(
`${label} returned HTTP 429 (rate limited)`,
'Homebrew throttles bursts; wait a few seconds 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 malformed JSON: ${err?.message ?? err}`);
}
return body;View on GitHub (pinned to 49907e53dc)
Solutions
- Verify the token on formulae.brew.sh or with `brew info <token>` and fix the typo.
- Check namespace: cask tokens (e.g. 'firefox') must hit /api/cask/, formula tokens /api/formula/.
- Handle EmptyResultError as 'not found' in the caller and present an empty/neutral result instead of a hard failure.
- If a package disappeared, pin to a known existing alternative or update the package list.
Example fix
// before
const f = await formula('wgett'); // 404 -> EmptyResultError
// after
try {
const f = await formula('wgett');
} catch (err) {
if (err instanceof EmptyResultError) return null; // treat as not found
throw err;
}
// or fix the token: await formula('wget'); Defensive patterns
Strategy: fallback
Validate before calling
const TOKEN = /^[A-Za-z0-9][A-Za-z0-9._+@-]*$/;
function tokenLooksValid(token) {
return typeof token === 'string' && token.length <= 100 && TOKEN.test(token);
}
// syntactic check only — existence still requires the API (404 = not found) Type guard
null
Try / catch
try {
const data = await brewFetch(url, label);
return data;
} catch (err) {
if (err instanceof EmptyResultError) return null; // 404: package not found
throw err;
} Prevention
- Verify package names with `brew info <token>` or formulae.brew.sh before scripting.
- Keep formula and cask namespaces separate; use the matching /api/formula/ or /api/cask/ path.
- Refresh cached package lists periodically — packages get renamed/removed.
- Treat EmptyResultError as 'no data', not as an infrastructure failure.
When it happens
Trigger: Requesting a formula/cask that doesn't exist: brewFetch('https://formulae.brew.sh/api/formula/wgett.json', ...) (typo); using a cask token against the formula endpoint or vice versa; requesting an analytics type/window combination that has no static file.
Common situations: Typo'd package names; packages that were renamed or deleted from Homebrew; mixing formula and cask namespaces; stale cached lists of package names referencing removed packages.
Related errors
- Lichess returned 404 for ${url}.
- REST Countries returned 404 for ${url}.
- Chess.com returned 404 for ${url}
- crates.io returned 404 for ${url}.
- Flathub returned 404 for ${url}.
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/816bb5cd54b0db7b.
Report an issue: GitHub.