jackwener/OpenCLI · error · CliError

FETCH_ERROR

FETCH_ERROR

Error message

HTTP ${resp.status}

What it means

The google suggest command calls Google's completion endpoint (suggestqueries.google.com/complete/search?client=firefox) and throws this CliError with code FETCH_ERROR when the HTTP response is not ok. It converts any non-2xx status into a single FETCH_ERROR with a network-connection hint.

Source

Thrown at clis/google/suggest.js:25

cli({
    site: 'google',
    name: 'suggest',
    access: 'read',
    description: 'Get Google search suggestions',
    strategy: Strategy.PUBLIC,
    browser: false,
    args: [
        { name: 'keyword', positional: true, required: true, help: 'Search query' },
        { name: 'lang', default: 'zh-CN', help: 'Language code' },
    ],
    columns: ['suggestion'],
    func: async (args) => {
        const keyword = encodeURIComponent(args.keyword);
        const lang = encodeURIComponent(args.lang);
        const url = `https://suggestqueries.google.com/complete/search?client=firefox&q=${keyword}&hl=${lang}`;
        const resp = await fetch(url);
        if (!resp.ok) {
            throw new CliError('FETCH_ERROR', `HTTP ${resp.status}`, 'Check your network connection');
        }
        const data = await resp.json();
        // Response format: ["query", ["suggestion1", "suggestion2", ...]]
        const suggestions = Array.isArray(data) && Array.isArray(data[1]) ? data[1] : [];
        if (!suggestions.length) {
            throw new CliError('NOT_FOUND', 'No suggestions found', 'Try a different keyword');
        }
        return suggestions.map(s => ({ suggestion: s }));
    },
});

View on GitHub (pinned to 49907e53dc)

Solutions

  1. If 429, throttle request rate and add exponential backoff between suggest calls
  2. Send a browser-like User-Agent header if the endpoint returns 403
  3. Retry after a delay for 5xx statuses, which are usually transient
  4. Verify network/proxy connectivity if all requests fail
  5. Log resp.status so the actual cause (rate-limit vs server error) is visible

Example fix

// before
const resp = await fetch(url);
if (!resp.ok) throw new CliError('FETCH_ERROR', `HTTP ${resp.status}`, 'Check your network connection');
// after
const resp = await fetch(url, {headers: {'User-Agent': 'Mozilla/5.0'}});
if (resp.status === 429) await backoff();
if (!resp.ok) throw new CliError('FETCH_ERROR', `HTTP ${resp.status}`, 'Check your network connection');
Defensive patterns

Strategy: retry

Validate before calling

// validate keyword before calling
if (!keyword || !keyword.trim()) throw new Error('keyword required');

Type guard

function isSuggestPayload(data) {
  return Array.isArray(data) && Array.isArray(data[1]);
}

Try / catch

try {
  return await suggestCommand.func(args);
} catch (e) {
  if (e.code === 'FETCH_ERROR' && e.message.includes('429')) {
    await sleep(10000);
    return suggestCommand.func(args);
  }
  throw e;
}

Prevention

When it happens

Trigger: fetch() to the suggest endpoint returns resp.ok === false — typically HTTP 429 after too many autocomplete requests, 403 bot rejection, or a proxy/network layer returning an error status.

Common situations: Bulk keyword-research loops hammering the suggest endpoint from one IP; missing or blocked User-Agent causing 403; corporate proxy intercepting the request; transient Google-side 5xx.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


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