jackwener/OpenCLI · critical · CommandExecutionError

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

Error message

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

What it means

packagistFetch wraps the underlying fetch() call; when fetch itself rejects (network-level failure, not an HTTP error status), it rethrows as CommandExecutionError with this message plus the hint to check reachability of packagist.org. This indicates the request never got a response — DNS, TCP, TLS, or proxy failure.

Source

Thrown at clis/packagist/utils.js:61

    }
    const vendor = raw.slice(0, slash);
    const pkg = raw.slice(slash + 1);
    if (vendor.length > 100 || pkg.length > 100 || !SEGMENT.test(vendor) || !SEGMENT.test(pkg)) {
        throw new ArgumentError(
            `packagist package "${value}" is not a valid Composer name`,
            'Use lowercase letters / digits / "_-.", segments separated by single "_-." chars (max 100 chars each).',
        );
    }
    return { vendor, package: pkg, full: `${vendor}/${pkg}` };
}

export async function packagistFetch(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 packagist.org is reachable from this network.',
        );
    }
    if (resp.status === 404) {
        throw new EmptyResultError(label, `Packagist returned 404 for ${url}.`);
    }
    if (resp.status === 429) {
        throw new CommandExecutionError(
            `${label} returned HTTP 429 (rate limited)`,
            'Packagist throttles 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 network connectivity: curl -I https://packagist.org and compare.
  2. Verify DNS resolves packagist.org (nslookup/dig) and proxy env vars (HTTPS_PROXY) are correct.
  3. Connect to the required VPN or whitelist packagist.org in the firewall.
  4. Retry with backoff if the failure was transient.
  5. Catch CommandExecutionError and surface the reachability hint to the user.

Example fix

// before
const data = await body({ q: term }); // throws if offline

// after
try {
  const data = await body({ q: term });
} catch (e) {
  if (/request failed/.test(e.message)) {
    console.error('packagist.org unreachable — check network/proxy');
  }
  throw e;
}
Defensive patterns

Strategy: retry

Validate before calling

async function canReachPackagist() {
  try {
    const r = await fetch('https://packagist.org', { method: 'HEAD' });
    return r.ok || r.status < 500;
  } catch { return false; }
}
if (!(await canReachPackagist())) throw new Error('packagist.org unreachable — check network/proxy/VPN');

Type guard

null

Try / catch

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

Prevention

When it happens

Trigger: Calling body (which calls packagistFetch) while offline; DNS resolution failure for packagist.org; blocked egress firewall; invalid/crashing HTTP proxy from HTTPS_PROXY; TLS interception with an untrusted cert; Node fetch abort due to timeout.

Common situations: Corporate network blocking packagist.org; VPN required but not connected; typo'd PACKAGIST_BASE override in a custom build; container without network access; transient ISP outage.

Related errors


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