{"record":{"id":"989b1e532ba98e29","repo":"upstash/context7","slug":"could-not-reach-url-detail-code-cod","errorCode":null,"errorMessage":"Could not reach ${url}: ${detail}${code ? ` (${code})` : \"\"}\\n${hint}","messagePattern":"Could not reach (.+?): (.+?)(.+?)\\)` : \"\"\\}\\\\n(.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/utils/auth.ts","lineNumber":214,"sourceCode":"}\n\nfunction describeConnectionError(error: unknown, url: string): string {\n  const { code, message } = getErrorCause(error);\n  const detail = message || (error instanceof Error ? error.message : String(error));\n  const hint = (code && CONNECTION_HINTS[code]) || DEFAULT_HINT;\n\n  return `Could not reach ${url}: ${detail}${code ? ` (${code})` : \"\"}\\n${hint}`;\n}\n\nasync function postForm(url: string, params: URLSearchParams): Promise<Response> {\n  try {\n    return await fetch(url, {\n      method: \"POST\",\n      headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n      body: params.toString(),\n    });\n  } catch (error) {\n    throw new Error(describeConnectionError(error, url));\n  }\n}\n\nasync function oauthRequest<T>(url: string, params: URLSearchParams, fallback: string): Promise<T> {\n  const response = await postForm(url, params);\n  if (!response.ok) {\n    throw new Error(await describeErrorResponse(response, fallback));\n  }\n  return (await response.json()) as T;\n}\n\n/** RFC 8628 §3.2 default poll interval when the server omits `interval`. */\nexport const DEFAULT_DEVICE_POLL_INTERVAL_SECONDS = 5;\n\nexport async function startDeviceAuthorization(\n  baseUrl: string,\n  clientId: string\n): Promise<DeviceAuthorizationResponse> {","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/upstash/context7/blob/ca15df0443ee770506fc4eb270d1efc71d483933/packages/cli/src/utils/auth.ts#L196-L232","documentation":"Thrown by postForm() when the underlying fetch() rejects during an OAuth HTTP request. The caught error is passed to describeConnectionError(), which extracts the cause's code/message and maps well-known errno codes (TLS, DNS, connection refused/reset, timeout) to a tailored remediation hint. The result is a multi-line message: 'Could not reach <url>: <detail> (<code>)\\n<hint>'.","triggerScenarios":"TLS interception by a corporate proxy (UNABLE_TO_VERIFY_LEAF_SIGNATURE, SELF_SIGNED_CERT_IN_CHAIN, CERT_HAS_EXPIRED); DNS failure for the auth host (ENOTFOUND, EAI_AGAIN); firewall/proxy refusing or resetting the connection (ECONNREFUSED, ECONNRESET, EHOSTUNREACH); connect timeout (UND_ERR_CONNECT_TIMEOUT, ETIMEDOUT).","commonSituations":"Developer on a corporate network whose TLS-inspecting proxy is not trusted by Node; VPN split-tunnel dropping the auth host; NODE_EXTRA_CA_CERTS not set to the org root CA; HTTPS_PROXY expected but Node does not honor it automatically; auth host moved/decommissioned.","solutions":["For TLS errors: export NODE_EXTRA_CA_CERTS=<path-to-org-root-ca.pem> and retry.","For DNS/connection errors: check VPN status and confirm the host resolves and is reachable (curl -v <url>).","If behind a proxy, route Node through it via HTTPS_PROXY / global-agent / undici's ProxyAgent, since Node ignores system proxy settings by default.","For ETIMEDOUT, raise connect timeout or move to a less restrictive network segment."],"exampleFix":"// before — Node ignores system proxy, fetch rejects with ECONNREFUSED\n// (no change at call site; fix the environment)\n\n// after — teach Node about the corporate proxy + CA before any fetch\nimport { setGlobalDispatcher, ProxyAgent } from \"undici\";\nprocess.env.NODE_EXTRA_CA_CERTS ||= \"/etc/ssl/certs/org-root-ca.pem\";\nsetGlobalDispatcher(new ProxyAgent(process.env.HTTPS_PROXY!));","handlingStrategy":"try-catch","validationCode":"// Pre-flight: confirm the host resolves and the TLS chain trusts before OAuth.\nimport { lookup } from \"node:dns/promises\";\nasync function canReach(url: string): Promise<boolean> {\n  try {\n    const host = new URL(url).hostname;\n    await lookup(host);\n    return true;\n  } catch {\n    return false;\n  }\n}\nif (!(await canReach(authUrl))) {\n  throw new Error(\"Auth host unreachable — check VPN/DNS/proxy.\");\n}","typeGuard":"// Narrow a thrown unknown to a connection-style error with an errno code.\nfunction hasErrnoCode(e: unknown): e is { cause: { code: string; message?: string } } {\n  return (\n    typeof e === \"object\" && e !== null &&\n    typeof (e as any).cause === \"object\" &&\n    typeof (e as any).cause?.code === \"string\"\n  );\n}","tryCatchPattern":"try {\n  await startDeviceAuthorization(baseUrl, clientId);\n} catch (e) {\n  const msg = e instanceof Error ? e.message : String(e);\n  if (/TLS|certificate/i.test(msg)) {\n    hintUser(\"Set NODE_EXTRA_CA_CERTS to your org root CA.\");\n  } else if (/ENOTFOUND|EAI_AGAIN/.test(msg)) {\n    hintUser(\"DNS failed — check VPN/network.\");\n  } else if (/ECONNREFUSED|ECONNRESET|EHOSTUNREACH/.test(msg)) {\n    hintUser(\"Connection blocked — firewall/proxy may be refusing it.\");\n  } else {\n    hintUser(\"If behind a proxy, configure HTTPS_PROXY (Node ignores system proxy).\");\n  }\n}","preventionTips":["On corporate networks, set NODE_EXTRA_CA_CERTS to the org root CA before any auth flow.","Configure an HTTPS_PROXY dispatcher for Node (undici/global-agent) since the runtime ignores system proxy settings.","Run a pre-flight DNS/TLS check before kicking off the device flow to fail fast with actionable guidance."],"tags":["network","oauth","proxy","tls","cli"],"backgroundTag":null,"analyzedSha":"ca15df0443ee770506fc4eb270d1efc71d483933","analyzedAt":"2026-08-12T13:31:48.440Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}