{"record":{"id":"95e4414be71673cf","repo":"mem0ai/mem0","slug":"failed-to-ping-server-error-message-unknown","errorCode":null,"errorMessage":"Failed to ping server: ${error.message || \"Unknown error\"}","messagePattern":"Failed to ping server: (.+?)","errorType":"exception","errorClass":"APIError","httpStatus":null,"severity":"error","filePath":"mem0-ts/src/client/mem0.ts","lineNumber":309,"sourceCode":"      if (!response || typeof response !== \"object\") {\n        throw new APIError(\"Invalid response format from ping endpoint\");\n      }\n\n      if (response.status !== \"ok\") {\n        throw new APIError(response.message || \"API Key is invalid\");\n      }\n\n      const { orgId, projectId, userEmail } = response;\n\n      if (orgId) this.organizationId = orgId;\n      if (projectId) this.projectId = projectId;\n      if (userEmail) this.telemetryId = userEmail;\n    } catch (error: any) {\n      // Pass through structured exceptions and APIError\n      if (error instanceof MemoryError || error instanceof APIError) {\n        throw error;\n      } else {\n        throw new APIError(\n          `Failed to ping server: ${error.message || \"Unknown error\"}`,\n        );\n      }\n    }\n  }\n\n  async add(\n    messages: Array<Message>,\n    options: AddMemoryOptions & Record<string, any> = {},\n  ): Promise<Array<Memory>> {\n    // Tightly scoped validation guard to resolve #5465\n    if (!messages || (Array.isArray(messages) && messages.length === 0)) {\n      throw new Error(\"Cannot process an empty messages payload.\");\n    }\n\n    const payload = this._preparePayload(messages, options);\n    const payloadKeys = Object.keys(payload);\n    this._captureEvent(\"add\", [payloadKeys]);","sourceCodeStart":291,"sourceCodeEnd":327,"githubUrl":"https://github.com/mem0ai/mem0/blob/001c235229be8795e3834520467bd0d661ed8f34/mem0-ts/src/client/mem0.ts#L291-L327","documentation":"This APIError is the catch-all wrapper around non-structured failures during the initialization ping to /v1/ping/: DNS failures, connection refused, TLS errors, timeouts, or fetch exceptions. Structured MemoryError/APIError cases are re-thrown unchanged; everything else is wrapped as 'Failed to ping server: <original message>' so the root cause text is preserved inside the message.","triggerScenarios":"host unreachable (DNS typo, firewall, service down), TLS certificate failure on a self-hosted endpoint, network timeout from sandboxed serverless runtimes, or an offline dev machine — any transport-level error during client init.","commonSituations":"Self-hosted server not started yet; egress-blocked containers; typo'd hostnames (api.mem0.ai vs api.mem0.ai.); corporate MITM proxies breaking TLS to the API.","solutions":["Read the suffixed original message — 'ENOTFOUND' means DNS/host typo, 'ECONNREFUSED' means the self-hosted server is down, certificate errors point at TLS/proxy issues.","Verify connectivity: curl -v ${host}/v1/ping/ from the same environment/container.","Start or health-check your self-hosted Mem0 server before constructing clients.","Open egress to the API host in container/serverless network policies."],"exampleFix":"# before: self-hosted server not running\nMEM0_HOST=http://localhost:8080\n\n# after: start it first\ndocker compose -f server/docker-compose.yaml up -d\n# then run the app","handlingStrategy":"retry","validationCode":"async function canReachPing(host: string, timeoutMs = 5000): Promise<boolean> {\n  try {\n    const c = new AbortController();\n    setTimeout(() => c.abort(), timeoutMs).unref?.();\n    const r = await fetch(`${host}/v1/ping/`, { signal: c.signal });\n    return r.ok;\n  } catch {\n    return false;\n  }\n}\n\nif (!(await canReachPing(host))) throw new Error(`Cannot reach ${host}/v1/ping/ — check network/DNS/server`);","typeGuard":"const isPingTransportError = (e: unknown): boolean =>\n  e instanceof Error && e.message.startsWith('Failed to ping server');","tryCatchPattern":"try {\n  const client = new MemoryClient({ apiKey, host });\n  await client.users();\n} catch (e) {\n  if (isPingTransportError(e)) {\n    await sleep(1000 * attempt++);\n    return retryInit(); // transient network failures are safe to retry\n  }\n  throw e;\n}","preventionTips":["Add a readiness probe on /v1/ping/ for self-hosted deployments.","Verify DNS/egress from the exact container or runtime that builds the client.","Distinguish ENOTFOUND/ECONNREFUSED in the message suffix to route to host-config vs server-down fixes."],"tags":["network","connectivity","ping","self-hosted"],"backgroundTag":null,"analyzedSha":"001c235229be8795e3834520467bd0d661ed8f34","analyzedAt":"2026-08-15T01:55:42.685Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}