{"record":{"id":"4411d41965de0870","repo":"alibaba/page-agent","slug":"network-error","errorCode":"NETWORK_ERROR","errorMessage":"Network request failed","messagePattern":"Network request failed","errorType":"exception","errorClass":"InvokeError","httpStatus":null,"severity":"error","filePath":"packages/llms/src/OpenAIClient.ts","lineNumber":88,"sourceCode":"\t\t}\n\t\tconst finalRequestBody = transformedBody ?? requestBody\n\n\t\t// 2. Call API\n\t\tlet response: Response\n\t\ttry {\n\t\t\tresponse = await this.fetch(`${this.config.baseURL}/chat/completions`, {\n\t\t\t\tmethod: 'POST',\n\t\t\t\theaders: {\n\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t...(this.config.apiKey && { Authorization: `Bearer ${this.config.apiKey}` }),\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify(finalRequestBody),\n\t\t\t\tsignal: abortSignal,\n\t\t\t})\n\t\t} catch (error: unknown) {\n\t\t\tif ((error as any)?.name === 'AbortError') throw error\n\t\t\tconsole.error(error)\n\t\t\tthrow new InvokeError(InvokeErrorTypes.NETWORK_ERROR, 'Network request failed', error)\n\t\t}\n\n\t\t// 3. Handle HTTP errors\n\t\tif (!response.ok) {\n\t\t\tlet errorData: any\n\t\t\ttry {\n\t\t\t\terrorData = await response.json()\n\t\t\t} catch (error) {\n\t\t\t\tif ((error as any)?.name === 'AbortError') throw error\n\t\t\t}\n\t\t\tconst errorMessage = errorData?.error?.message || response.statusText\n\n\t\t\tif (response.status === 401 || response.status === 403) {\n\t\t\t\tthrow new InvokeError(\n\t\t\t\t\tInvokeErrorTypes.AUTH_ERROR,\n\t\t\t\t\t`Authentication failed: ${errorMessage}`,\n\t\t\t\t\terrorData\n\t\t\t\t)","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/alibaba/page-agent/blob/d02db1ee7c41f5315beda88bab2fe935c580f662/packages/llms/src/OpenAIClient.ts#L70-L106","documentation":"The underlying fetch call to the OpenAI-compatible endpoint failed before receiving an HTTP response — DNS failure, connection refused, TLS error, network offline, or a non-abort fetch exception. The library re-throws AbortError untouched and wraps everything else in a NETWORK_ERROR InvokeError with the original error as cause. The raw error is also console.error'd before throwing.","triggerScenarios":"fetch() to config.baseURL rejects: unreachable host (wrong baseURL like localhost port not running), DNS resolution failure, self-signed cert rejected, firewall/proxy blocking the request, browser CORS failure, or the page going offline. Any caller of invoke() can hit this.","commonSituations":"Typo in baseURL (missing scheme, wrong port); corporate proxy intercepting HTTPS; running a local LLM server (ollama/llama.cpp) that isn't started; extension making cross-origin requests without host permissions; offline dev environment.","solutions":["Verify the endpoint is reachable: curl -v <baseURL>/chat/completions from the same machine/network","Check baseURL spelling — scheme, host, port, and path prefix (e.g. /v1)","If behind a proxy or using a local server, confirm it's running and listening on the expected interface","In a browser/extension context, check CORS headers or host_permissions for the baseURL origin","Inspect the preserved cause (InvokeError cause) and the console.error output for the precise fetch failure reason"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// verify reachability before first use (Node)\nawait fetch(new URL('/models', cfg.baseURL), { method: 'HEAD' })\n  .then(r => console.log('endpoint reachable:', r.status))\n  .catch(err => { throw new Error(`Unreachable baseURL ${cfg.baseURL}: ${err.message}`) })","typeGuard":"const isNetworkError = (e: unknown): e is InvokeError =>\n  e instanceof InvokeError && e.code === 'NETWORK_ERROR'","tryCatchPattern":"try {\n  await client.invoke(req)\n} catch (e) {\n  if (isNetworkError(e)) {\n    await backoff(Math.random() * 1000) // transient DNS/socket issues often clear\n    return client.invoke(req)\n  }\n  throw e\n}","preventionTips":["Validate baseURL format and reachability at startup","In extensions, declare host_permissions for the endpoint origin","Keep AbortError propagation intact — check e.name === 'AbortError' before treating as network failure"],"tags":["network","fetch","openai-client"],"backgroundTag":"network-request-failed","analyzedSha":"d02db1ee7c41f5315beda88bab2fe935c580f662","analyzedAt":"2026-08-28T19:39:48.634Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}