jackwener/OpenCLI · critical · CliError

FETCH_ERROR

FETCH_ERROR

Error message

Unable to reach paperreview.ai: ${getErrorMessage(error)}

What it means

requestJson() performs fetch(`${PAPERREVIEW_BASE_URL}${pathname}`). If the fetch itself rejects — before any HTTP response is received — it throws FETCH_ERROR 'Unable to reach paperreview.ai: <cause>'. This wraps network-level failures such as DNS resolution failure, connection refused/timeout, or TLS errors.

Source

Thrown at clis/paperreview/utils.js:98

        buffer = await fs.readFile(resolvedPath);
    }
    catch {
        throw new CliError('FILE_READ_ERROR', `Unable to read file: ${resolvedPath}`, 'Check file permissions and try again');
    }
    return {
        buffer,
        fileName,
        resolvedPath,
        sizeBytes: buffer.byteLength,
    };
}
export async function requestJson(pathname, init = {}) {
    let response;
    try {
        response = await fetch(`${PAPERREVIEW_BASE_URL}${pathname}`, init);
    }
    catch (error) {
        throw new CliError('FETCH_ERROR', `Unable to reach paperreview.ai: ${getErrorMessage(error)}`, 'Check your network connection and try again');
    }
    const rawText = await response.text();
    let payload = rawText;
    if (rawText) {
        try {
            payload = JSON.parse(rawText);
        }
        catch {
            payload = rawText;
        }
    }
    return { response, payload };
}
export function ensureSuccess(response, payload, fallback, hint) {
    if (!response.ok) {
        const code = response.status === 404 ? 'NOT_FOUND' : 'API_ERROR';
        throw new CliError(code, toErrorMessage(payload, fallback), hint);
    }

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Check basic connectivity: curl -v https://paperreview.ai — fix network/VPN/DNS if it fails
  2. Set proxy env vars if behind a corporate proxy: export HTTPS_PROXY=http://proxy:port
  3. If TLS interception is used, install the corporate CA into the Node trust store (NODE_EXTRA_CA_CERTS=/path/ca.pem)
  4. Retry after confirming the service is up (status.paperreview.ai or similar) in case of transient outage

Example fix

// before
await requestJson('/api/upload-url', { method: 'POST' }); // fails behind proxy
// after
// $ export HTTPS_PROXY=http://corp-proxy:8080
// $ export NODE_EXTRA_CA_CERTS=/etc/corp/root-ca.pem
await requestJson('/api/upload-url', { method: 'POST' });
Defensive patterns

Strategy: retry

Validate before calling

import net from 'node:net';
import tls from 'node:tls';
async function canReachPaperreview() {
    try {
        await new Promise((resolve, reject) => {
            const socket = tls.connect({ host: 'paperreview.ai', port: 443, servername: 'paperreview.ai', timeout: 5000 }, resolve);
            socket.on('error', reject);
            socket.on('timeout', () => { socket.destroy(); reject(new Error('timeout')); });
        });
        return true;
    } catch { return false; }
}

Try / catch

async function requestJsonWithRetry(pathname, init, attempts = 3) {
    for (let i = 1; i <= attempts; i++) {
        try { return await requestJson(pathname, init); }
        catch (e) {
            if (e?.code === 'FETCH_ERROR' && i < attempts) { await new Promise(r => setTimeout(r, 1000 * 2 ** (i - 1))); continue; }
            if (e?.code === 'FETCH_ERROR') console.error('Network down:', e.message, '— check VPN/proxy/DNS (HTTPS_PROXY, NODE_EXTRA_CA_CERTS)');
            throw e;
        }
    }
}

Prevention

When it happens

Trigger: Any requestJson() call (upload URL request, confirm, status, review fetch) where fetch() rejects: no network, DNS failure for paperreview.ai, proxy/firewall blocking HTTPS, TLS interception with untrusted CA, IPv6-only environment lacking IPv4 route, offline machine.

Common situations: Corporate proxy without HTTPS_PROXY env set; VPN down; DNS server unreachable; self-signed MITM proxy (Zscaler/Netgear) whose CA is not in the trust store; airport/captive portal not yet authenticated.

Related errors


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