jackwener/OpenCLI · error · CommandExecutionError

${label} request failed: ${err?.message ?? err}

Error message

${label} request failed: ${err?.message ?? err}

What it means

CommandExecutionError thrown by pypiFetch when the underlying fetch itself rejects — i.e. the request never got an HTTP response. The label identifies which call (e.g. 'pypi package <name>') failed, and the original error message is appended.

Source

Thrown at clis/pypi/utils.js:30

export function requirePackageName(value) {
    const s = String(value ?? '').trim();
    if (!s) throw new ArgumentError('pypi package name is required (e.g. "requests", "pandas")');
    if (!PKG_NAME.test(s)) {
        throw new ArgumentError(
            `pypi package name "${value}" is not a valid distribution name`,
            'PyPI accepts ASCII letters / digits / "._-" with no leading or trailing separator.',
        );
    }
    return s;
}

export async function pypiFetch(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 pypi.org / pypistats.org are reachable from this network.',
        );
    }
    if (resp.status === 404) {
        throw new EmptyResultError(label, `PyPI returned 404 for ${url}.`);
    }
    if (resp.status === 429) {
        throw new CommandExecutionError(
            `${label} returned HTTP 429 (rate limited)`,
            'PyPI throttles unauthenticated bursts; wait a few seconds and retry.',
        );
    }
    if (!resp.ok) {
        throw new CommandExecutionError(`${label} returned HTTP ${resp.status}`);
    }
    let body;
    try {

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Check basic connectivity: curl -I https://pypi.org
  2. Check proxy env vars (HTTP_PROXY/HTTPS_PROXY) are correct if behind a proxy
  3. Retry after transient network issues; add retry/backoff around CLI calls
  4. Verify DNS resolves pypi.org (nslookup pypi.org)

Example fix

// before
const data = await pypiFetch(url, 'pypi pkg'); // throws on network blip
// after
let data;
for (let i = 0; i < 3; i++) {
  try { data = await pypiFetch(url, 'pypi pkg'); break; }
  catch (e) { if (i === 2) throw e; await new Promise(r => setTimeout(r, 2 ** i * 500)); }
}
Defensive patterns

Strategy: retry

Validate before calling

// pre-check reachability
const ok = await fetch('https://pypi.org/simple/', { method: 'HEAD' }).then(r => r.ok).catch(() => false);
if (!ok) throw new Error('pypi.org unreachable from this network');

Type guard

null

Try / catch

async function fetchWithRetry(url, label, tries = 3) {
  for (let i = 0; ; i++) {
    try { return await pypiFetch(url, label); }
    catch (e) {
      if (i >= tries - 1 || !/request failed/i.test(e.message)) throw e;
      await new Promise(r => setTimeout(r, 2 ** i * 500));
    }
  }
}

Prevention

When it happens

Trigger: Any pypiFetch call where DNS resolution fails, the connection is refused/times out, TLS fails, or the process lacks network access to pypi.org or pypistats.org.

Common situations: Working offline or on a flaky network; corporate firewalls blocking pypi.org; misconfigured proxy environment variables; DNS outages; IPv6-only environments.

Related errors


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