bytedance/deer-flow · error · Mem0APIError

mem0 {method} {path} returned malformed JSON: {e}

Error message

mem0 {method} {path} returned malformed JSON: {e}

What it means

Raised as Mem0APIError by Mem0Client._request when the server returns HTTP < 400 with a non-empty body that is not valid JSON (json.JSONDecodeError on resp.json()). The client expects JSON responses ('Accept: application/json'); malformed JSON means something other than the real mem0 API answered — or the response stream was corrupted/truncated.

Source

Thrown at backend/packages/harness/deerflow/agents/memory/backends/mem0/client.py:59

    def close(self) -> None:
        self._http.close()

    def _request(self, method: str, path: str, **kwargs: Any) -> dict[str, Any]:
        try:
            resp = self._http.request(method, path, **kwargs)
        except httpx.HTTPError as e:
            raise Mem0APIError(f"mem0 request failed: {e}") from e
        if resp.status_code == 401:
            raise Mem0AuthError("mem0 authentication failed (check the API key)")
        if resp.status_code >= 400:
            raise Mem0APIError(f"mem0 {method} {path} -> {resp.status_code}: {resp.text[:200]}")
        if not resp.content:
            return {}
        try:
            return resp.json()
        except json.JSONDecodeError as e:
            raise Mem0APIError(f"mem0 {method} {path} returned malformed JSON: {e}") from e

    def add_memories(
        self,
        *,
        messages: list[dict[str, str]],
        user_id: str | None = None,
        agent_id: str | None = None,
        run_id: str | None = None,
    ) -> dict[str, Any]:
        """Queue extraction (async server-side; response carries an event_id)."""
        body: dict[str, Any] = {"messages": messages}
        if user_id:
            body["user_id"] = user_id
        if agent_id:
            body["agent_id"] = agent_id
        if run_id:
            body["run_id"] = run_id
        return self._request("POST", "/v3/memories/add/", json=body)

View on GitHub (pinned to 1dd6ba1acb)

Solutions

  1. curl the base_url from the Gateway host and inspect Content-Type/body — if you get HTML, the URL or the proxy is wrong
  2. Fix base_url to point directly at the mem0 API root, bypassing any UI-serving host or path
  3. Exclude the mem0 host from corporate proxy interception (NO_PROXY) or configure the proxy correctly
  4. If self-hosted behind nginx/ingress, verify the route proxies to the mem0 service and passes Accept/Content-Type headers untouched

Example fix

# before
export HTTPS_PROXY=http://proxy.corp:3128   # intercepts api.mem0.ai, returns HTML

# after
export HTTPS_PROXY=http://proxy.corp:3128
export NO_PROXY=api.mem0.ai   # or fix base_url to the real API host
Defensive patterns

Strategy: try-catch

Validate before calling

import httpx

def mem0_returns_json(base_url: str) -> bool:
    try:
        r = httpx.get(base_url, timeout=5, headers={"Accept": "application/json"})
        ct = r.headers.get("content-type", "")
        return "json" in ct or r.content[:1] in (b"{", b"[")
    except httpx.HTTPError:
        return False

Try / catch

from deerflow.agents.memory.backends.mem0.client import Mem0APIError

try:
    data = client.get_context(user_id=u)
except Mem0APIError as e:
    if "malformed JSON" in str(e):
        # something other than the mem0 API answered (proxy/captive portal/wrong URL)
        # do NOT retry — diagnose the base_url/proxy path first
        raise RuntimeError(f"non-API endpoint answered at base_url: {e}") from e
    raise

Prevention

When it happens

Trigger: A request succeeds status-wise but the body is HTML (captive portal, proxy error page, a reverse proxy serving the frontend on the same host), a truncated response from a flaky proxy, or a misconfigured base_url landing on a non-API server.

Common situations: Corporate proxy or Wi-Fi captive portal intercepting HTTPS and returning an HTML page; base_url pointing at a web UI instead of the API; self-hosted ingress misrouting /memories traffic to a static server; response compression handled incorrectly by an intermediate proxy.

Understand the failure class

Related errors


AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14). Data as JSON: /api/errors/ba62eae1b4bacea1. Report an issue: GitHub.