{"record":{"id":"8d46ee4a81c1a632","repo":"jackwener/OpenCLI","slug":"fetch-error-8d46ee","errorCode":"FETCH_ERROR","errorMessage":"Browser fetch failed for ${targetUrl}: ${result.error}","messagePattern":"Browser fetch failed for (.+?): (.+?)","errorType":"error_code","errorClass":"CliError","httpStatus":null,"severity":"error","filePath":"src/browser/base-page.ts","lineNumber":261,"sourceCode":"            error: error instanceof Error ? error.message : String(error),\n          };\n        } finally {\n          clearTimeout(timer);\n        }\n      })()\n    `, { request }) as {\n      ok?: boolean;\n      status?: number;\n      statusText?: string;\n      url?: string;\n      contentType?: string;\n      text?: string;\n      error?: string;\n    };\n\n    const targetUrl = result.url || url;\n    if (result.error) {\n      throw new CliError(\n        'FETCH_ERROR',\n        `Browser fetch failed for ${targetUrl}: ${result.error}`,\n        'Check that the page is reachable and the current browser profile has access.',\n      );\n    }\n    if (!result.ok) {\n      throw new CliError(\n        'FETCH_ERROR',\n        `HTTP ${result.status ?? 0}${result.statusText ? ` ${result.statusText}` : ''} from ${targetUrl}`,\n        previewText(result.text),\n      );\n    }\n\n    const text = result.text ?? '';\n    if (!text.trim()) return null;\n    try {\n      return JSON.parse(text);\n    } catch {","sourceCodeStart":243,"sourceCodeEnd":279,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/src/browser/base-page.ts#L243-L279","documentation":"fetchJson (src/browser/base-page.ts:261) performs fetch inside the page context (via page.evaluate) so the request uses the browser's cookies and profile. When the in-page fetch reports an error (network failure, blocked request, aborted), the result carries result.error and the method throws CliError with code FETCH_ERROR, plus a hint to check reachability and profile access.","triggerScenarios":"The in-page fetch rejects or returns {error: ...}: DNS failure, ERR_BLOCKED_BY_CLIENT (ad blocker), mixed-content blocking (HTTPS page fetching HTTP URL), CORS handled as a network error, request timeout/abort, or the page navigating away mid-fetch.","commonSituations":"Extensions/ad-blockers cancelling the request; fetching http:// endpoints from https:// pages; corporate proxy/VPN blocking the host; fetching an internal hostname from a page loaded on the public internet; service worker intercepting and failing the request.","solutions":["Open the target URL directly in the browser tab to confirm reachability and fix DNS/proxy/VPN issues.","If mixed content is the cause, use the HTTPS form of the URL.","Temporarily disable ad blockers/content blockers or whitelist the domain, since ERR_BLOCKED_BY_CLIENT surfaces as a fetch error.","Catch the CliError, inspect result.error in the message, and fall back to a server-side (Node) fetch if browser-context fetch isn't required.","Check the page's service workers and extension content scripts that may intercept or cancel fetches."],"exampleFix":"// before\nconst data = await page.fetchJson('http://api.internal.local/endpoint');\n// after\nconst data = await page.fetchJson('https://api.internal.local/endpoint'); // or try/catch FETCH_ERROR and fall back to server-side fetch","handlingStrategy":"try-catch","validationCode":"// reachability pre-check before the browser-context fetch:\nconst reachable = await page.evaluate(`(async () => { try { const r = await fetch(${JSON.stringify(url)}, { method: 'HEAD' }); return r.ok || r.status > 0; } catch { return false; } })()`);\nif (!reachable) console.warn('URL unreachable from page context:', url);","typeGuard":"function isCliError(err: unknown, code?: string): err is CliError {\n  return err instanceof CliError || (typeof err === 'object' && err !== null && (err as any).code === (code ?? 'FETCH_ERROR'));\n}","tryCatchPattern":"try {\n  return await page.fetchJson(url);\n} catch (err) {\n  if (isCliError(err, 'FETCH_ERROR')) {\n    console.warn(`browser fetch failed: ${err.message}; hint: ${err.hint}`);\n    return serverFetchJson(url); // fall back to Node-side fetch\n  }\n  throw err;\n}","preventionTips":["Use HTTPS URLs to avoid mixed-content blocking from https pages.","Whitelist the domain in ad blockers/extensions that can cancel fetches (ERR_BLOCKED_BY_CLIENT).","Confirm reachability by opening the URL in the tab before automated fetches.","Fall back to server-side fetch when cookies from the browser profile aren't required."],"tags":["network","fetch","browser-context","http"],"backgroundTag":"fetch-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}