jackwener/OpenCLI · error · CommandExecutionError

${label} returned HTTP ${res.status}

Error message

${label} returned HTTP ${res.status}

What it means

This error is thrown by dblpFetch when the dblp.org HTTP response has a non-ok status other than 429 and 404. It means the raw HTTP request itself failed with an unexpected status code (e.g. 500, 502, 403). The hint advises opening the same URL in a browser to inspect the response.

Source

Thrown at clis/dblp/utils.js:50

    try {
        res = await fetch(url, {
            headers: {
                accept,
                'user-agent': 'opencli-dblp/1.0 (+https://github.com/jackwener/opencli)',
            },
        });
    }
    catch (err) {
        throw new CommandExecutionError(`${label} request failed: ${err?.message ?? err}`, 'Check that dblp.org is reachable from this network.');
    }
    if (!res.ok) {
        if (res.status === 429) {
            throw new CommandExecutionError(`${label} returned HTTP 429 (rate limited)`, 'dblp throttles clients that fetch too aggressively. Wait a few seconds and retry, or lower --limit.');
        }
        if (res.status === 404) {
            throw new EmptyResultError(label, 'dblp returned 404 — the requested record may not exist.');
        }
        throw new CommandExecutionError(`${label} returned HTTP ${res.status}`, 'Inspect the response in a browser at the same URL for more context.');
    }
    return res;
}

export async function dblpFetchJson(path, label) {
    const res = await dblpFetch(`${DBLP_ORIGIN}${path}`, label, 'application/json');
    let body;
    try {
        body = await res.json();
    }
    catch (err) {
        throw new CommandExecutionError(`${label} returned malformed JSON: ${err?.message ?? err}`);
    }
    const statusCode = String(body?.result?.status?.['@code'] ?? '').trim();
    if (!statusCode) {
        throw new CommandExecutionError(
            `${label} returned JSON without result.status.@code`,
            'dblp changed its JSON envelope or returned a partial error payload; inspect the raw response in a browser.',

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Open the same dblp URL in a browser to see the actual response/error page
  2. Wait a few minutes and retry — most 5xx are transient dblp-side outages
  3. Check whether a corporate proxy/firewall is blocking dblp.org (403) and whitelist it if needed
  4. Check https://dblp.org status or the dblp FAQ for known incidents

Example fix

// before
const res = await fetch('https://dblp.org/search/publ/api?q=test&format=json');
// (fails with "dblp search returned HTTP 502")
// after
await new Promise(r => setTimeout(r, 3000)); // brief backoff for transient 5xx
const res = await fetch('https://dblp.org/search/publ/api?q=test&format=json');
Defensive patterns

Strategy: retry

Validate before calling

const url = new URL('https://dblp.org/search/publ/api');
if (!['https:'].includes(url.protocol)) throw new Error('dblp requires https');

Type guard

function isOkResponse(res) { return typeof res.status === 'number' && res.status >= 200 && res.status < 300; }

Try / catch

try {
  const json = await dblpFetchJson(path, 'dblp search');
} catch (err) {
  if (/returned HTTP \d+/.test(err.message) && !/429|404/.test(err.message)) {
    // transient 5xx: back off and retry once or twice
    await new Promise(r => setTimeout(r, 3000));
    return retryFetch(path);
  }
  throw err;
}

Prevention

When it happens

Trigger: dblpFetch receives res.ok === false with status not 429/404 — e.g. dblp returns 500/502 during an outage, a proxy/CDN returns 403, or a captive portal intercepts the request.

Common situations: dblp.org temporary outages or maintenance; corporate proxies or firewalls blocking dblp.org (403); Cloudflare-level errors (5xx) between the client and dblp.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/f472ce6ce975385d. Report an issue: GitHub.