jackwener/OpenCLI · critical · CommandExecutionError

stack exchange request failed: ${error?.message || error}

Error message

stack exchange request failed: ${error?.message || error}

What it means

CommandExecutionError thrown by seFetch when the underlying fetch() call itself rejects — the request never got an HTTP response. The original error message is wrapped as `stack exchange request failed: <cause>` so DNS failures, TLS errors, connection resets, and timeouts all surface under this single prefix.

Source

Thrown at clis/stackoverflow/utils.js:60

    if (searchParams) {
        for (const [k, v] of Object.entries(searchParams)) {
            if (v == null || v === '') continue;
            url.searchParams.set(k, String(v));
        }
    }
    if (!url.searchParams.has('site')) url.searchParams.set('site', SE_SITE);

    let resp;
    try {
        resp = await fetch(url, {
            headers: {
                'Accept': 'application/json',
                'Accept-Encoding': 'gzip',
                'User-Agent': UA,
            },
        });
    } catch (error) {
        throw new CommandExecutionError(`stack exchange request failed: ${error?.message || error}`);
    }
    if (resp.status === 429) {
        throw new CommandExecutionError('stack exchange returned HTTP 429 (rate limited)', 'Wait a few seconds and retry, or lower --limit.');
    }
    if (!resp.ok) {
        let body = '';
        try { body = (await resp.json())?.error_message || ''; } catch { /* ignore */ }
        throw new CommandExecutionError(`stack exchange HTTP ${resp.status}: ${body || resp.statusText}`);
    }
    let data;
    try {
        data = await resp.json();
    } catch (error) {
        throw new CommandExecutionError(`stack exchange returned malformed JSON: ${error?.message || error}`);
    }
    if (data?.error_id) {
        throw new CommandExecutionError(
            `stack exchange API error: ${data.error_message || data.error_name}`,

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Check connectivity: `curl -sI https://api.stackexchange.com/2.3/info?site=stackoverflow`.
  2. Fix DNS/VPN/proxy issues; if behind a MITM proxy, configure NODE_EXTRA_CA_CERTS or HTTPS_PROXY correctly.
  3. Ensure Node >= 18 so global fetch exists.
  4. Retry with backoff on transient network errors before giving up.

Example fix

// before
const data = await seFetch(path);
// after
let data;
for (let i = 0; i < 3; i++) {
  try { data = await seFetch(path); break; }
  catch (e) {
    if (!String(e.message).startsWith('stack exchange request failed') || i === 2) throw e;
    await new Promise(r => setTimeout(r, 1000 * 2 ** i));
  }
}
Defensive patterns

Strategy: retry

Validate before calling

if (typeof fetch !== 'function') throw new Error('global fetch unavailable; requires Node >= 18');
// optional preflight:
await fetch('https://api.stackexchange.com/2.3/info?site=stackoverflow', { method: 'HEAD' });

Try / catch

async function fetchWithRetry(path, attempts = 3) {
  for (let i = 0; ; i++) {
    try {
      return await seFetch(path);
    } catch (e) {
      const transient = String(e.message).startsWith('stack exchange request failed');
      if (!transient || i >= attempts - 1) throw e;
      await new Promise(r => setTimeout(r, 1000 * 2 ** i));
    }
  }
}

Prevention

When it happens

Trigger: No network/DNS failure resolving api.stackexchange.com; TLS/proxy interception (corporate MITM); IPv6 issues; Node runtime without global fetch (Node < 18); firewall blocking outbound 443.

Common situations: Working offline or on flaky Wi-Fi; corporate proxy requiring custom CA certs; DNS blocked by VPN; CI runners without egress to api.stackexchange.com.

Related errors


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