ErrLookup › Background articles › "empty response", "returned no data", "empty embeddings": what HTTP 200-with-empty-body errors mean across libraries
"empty response", "returned no data", "empty embeddings": what HTTP 200-with-empty-body errors mean across libraries
"empty response" errors — messages like "External assistant returned an empty response.", "Ollama returned empty embeddings for batch!", "No results found in the response", or "Frankfurter currencies endpoint returned no data" — are raised when a library receives a successful (usually 2xx) HTTP response whose body is empty, null, or missing the expected fields. You hit them when an upstream API returns nothing usable, a proxy strips the body, or the wrong model/endpoint/IDs yield zero rows. This page explains the family and how to tell empty-but-healthy from a broken integration.
Distilled from 96 documented records across 36 repositories.
Background
This family sits at the boundary between transport errors and data errors. The request reached the server, authentication usually passed, and the status code was a success — yet the body decoded to nothing: an empty string, a null JSON object, a missing results array, or an envelope whose expected key is absent. Libraries guard against this because dereferencing the nothing would crash unpredictably (a TypeError on None in Python, a nil-pointer panic in Go, a silently wrong-length embedding array). So they raise a named error instead: yt-dlp raises ExtractorError when data.archives is empty, LiteLLM raises ValueError when the Bedrock rerank response has no 'results' key, k6 refuses to dereference a nil OpenAPI-client response and reports a generic communication failure, and agenticSeek checks for None before touching response.choices[0].message.content.
Why does a server answer 200 with nothing? The records show recurring mechanisms: the upstream service genuinely has no rows (a weekend date with no market data, a delisted ticker, an MCP server with no tools, an Eastmoney longhu window on a holiday); the upstream returned an error-shaped or refused payload with a success status (Facebook returning an empty 200 body for OAuth failures, Gemini emptying candidates on over-restrictive safety settings, Bedrock error payloads arriving with 2xx); a proxy or gateway stripped or truncated the body (nginx empty responses, 204s, corporate middleboxes, a wrong FRANKFURTER_URL mirror); or the wrong thing was asked for (a chat model routed to an embeddings endpoint, a --host pointing at the main server instead of the admin recovery endpoint, an acctId no longer in the SimpleFin account set).
From the caller's side, the family varies in how much context each library preserves. Some messages are generic catch-alls — k6's errUnknown and yt-dlp's "Failed to extract any player response" hide a nil or unusable payload behind a vague complaint. Others embed the evidence: OpenCLI interpolates the secucode or date into "No shareholder data for ${secucode}" and echoes the upstream error in "LinkedIn Learning courses lookup failed: ${result?.error ?? 'no payload'}"; LiteLLM echoes the full raw response in the ValueError. How they're handled downstream also differs: we-promise/sure catches its own Assistant::Error and attaches it to the chat inline; anything-llm re-wraps the Mistral empty-embeddings throw inside a broader try block; agenticSeek re-wraps None checks as "OpenAI API error: ...". Whether an empty response is fatal or an expected outcome is likewise library-specific — OpenCLI treats NO_DATA on money-flow queries as a warning-level condition, while actualbudget maps SimpleFin's NO_DATA to "needs re-link or no data yet" in scheduled syncs.
A useful diagnostic split within the family: some of these errors mean the API is healthy and there is simply no data (weekends, delisted securities, new IPOs, dates before records exist), while others mean something in the chain swallowed content the service intended to return (proxies, schema changes, misrouted models, safety-filtered refusals). The same message text can sit on either side depending on the library — several records explicitly tell you to distinguish "no data" from transport or auth failures in your own alerting.
Common causes
- Genuinely no data for the request. The upstream has zero rows: weekend/holiday dates in market-data APIs, delisted or pre-IPO securities, SimpleFin accounts filtered out by a startDate, or MCP servers with no tools. The API is healthy; the answer is empty. Treat these as expected outcomes, not outages.
- Proxy or gateway stripping the body. An intermediary returns 200 with an empty or truncated body: nginx empty responses, 204s, corporate proxies, or a misconfigured base URL pointing at a mirror that answers 200 with no content. AnythingLLM, agenticSeek, sure, and k6 all cite this pattern.
- Wrong model or endpoint configuration. A chat model (llama3, mistral) routed to an embeddings call, a non-rerank model sent to Bedrock's rerank endpoint, or --host pointing at the main InfluxDB server instead of the admin token recovery endpoint. The server succeeds but produces nothing usable or omits the expected payload.
- Upstream error disguised as success. Some services answer 2xx with an error-shaped or empty body: Facebook returns a zero-length 200 for OAuth failures on /oauth/client_code, Bedrock returns error payloads with success status, Gemini can empty its candidates on safety refusal. The status code lies; the empty body is the error.
- API schema or envelope change. The expected key moved or vanished — Eastmoney renaming data.result.data or data.data.diff, YouTube changing player-response shapes so traversal yields nothing, or BR's media XML no longer matching the extractor's XPath. Older client/SDK versions fail to decode the new shape into a usable result.
- Expired, missing, or partial authentication. Expired LinkedIn cookies route to a login page whose JSON is undefined; a wrong-app or expired Facebook token yields an empty 200; SimpleFin accounts pending bank re-auth return nothing. Auth failures that surface as empty successful responses rather than 401s.
- Transient service or transport hiccups. Keep-alive connection races (k6), load-balancer blips (Frankfurter health probes), throttled Bedrock invocations returning unusable bodies, or Bilibili risk control mid-pagination. These usually clear on a simple retry.
- Empty or degenerate inputs. Embedding an empty list or whitespace-only strings can shrink a batch to nothing server-side, making the response's data array empty. OpenCLI's LinkedIn calls and anything-llm's Mistral embedder both flag empty-string inputs as a direct trigger.
What usually fixes it
- [object Object]
- [object Object]
- [object Object]
- [object Object]
- [object Object]
- [object Object]
Go deeper
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
- Connection failures: ECONNREFUSED, ECONNRESET, and friends — why connections get refused, reset, or dropped.
- HTTP status errors: handling 4xx and 5xx responses — how to handle 4xx and 5xx responses properly.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Documented occurrences
- External assistant returned an empty response. (we-promise/sure)
- token creation to return full token info (influxdata/influxdb)
- generate_client_code received an error: empty response body (arsduo/koala)
- OpenAI response is empty. (Fosowl/agenticSeek)
- tools/list returned an empty response (siyuan-note/siyuan)
- an error occurred communicating with k6 Cloud (grafana/k6)
- Ollama returned empty embeddings for batch! (Mintplex-Labs/anything-llm)
- NO_DATA: No shareholder data for ${secucode} (jackwener/OpenCLI)
- Update MCP connection response was incomplete. (different-ai/openwork)
- No prices found for security #{symbol} on date #{date} (we-promise/sure)
- Failed to retrieve video list for page {page_num} (yt-dlp/yt-dlp)
- Failed to extract any player response (yt-dlp/yt-dlp)
- Anthropic response is empty. (Fosowl/agenticSeek)
- Update connection access response was incomplete. (different-ai/openwork)
- remote commit message was empty (nikivdev/code)
- Frankfurter currencies endpoint returned no data (we-promise/sure)
- mascot manifest: no renderable mascots (tinyhumansai/openhuman)
- No results found in the response={response} (BerriAI/litellm)
- LinkedIn Learning courses lookup failed: ${result?.error ?? 'no payload'} (jackwener/OpenCLI)
- Mistral returned empty embeddings for batch (Mintplex-Labs/anything-llm)
…and 76 more across the corpus — use search.
Honest provenance: generated on 2026-09-03 from AI-assisted analysis of the linked records. See how records are made.