MemPalace/mempalace · error · EmbeddingAPIError
Embedding API at {self._url} returned a non-object response:
Error message
Embedding API at {self._url} returned a non-object response: {data} What it means
Raised by _vectors_from_response when the parsed JSON body of an /v1/embeddings response is not a top-level object (dict). A conformant server returns {"data": [...]}; anything else — a bare list, a string, a number, null — cannot be validated further and would otherwise crash later with a cryptic KeyError or numpy error. The whole offending payload is echoed in the message for diagnosis.
Source
Thrown at mempalace/embedding.py:580
) from e
out.extend(self._vectors_from_response(data, len(batch)))
return out
def _vectors_from_response(self, data, n: int) -> list:
"""Validate one ``/v1/embeddings`` response and return L2-normed vectors.
Guards every way a non-conformant server could corrupt the store
silently: a missing/short ``data`` array, response ``index`` values
that aren't the contiguous ``0..n-1`` batch positions (sorting then
zipping positionally would otherwise misalign vectors with texts), and
malformed / ragged / base64 embedding payloads. All failures raise
:class:`EmbeddingAPIError` naming the endpoint rather than a cryptic
numpy error — a silent wrong result would break the 100%-recall promise.
"""
import numpy as np
if not isinstance(data, dict):
raise EmbeddingAPIError(
f"Embedding API at {self._url} returned a non-object response: {data}"
)
rows = data.get("data")
if not isinstance(rows, list):
raise EmbeddingAPIError(
f"Embedding API at {self._url} returned no 'data' array: {data.get('error', data)}"
)
if len(rows) != n:
raise EmbeddingAPIError(
f"Embedding API at {self._url} returned {len(rows)} embeddings for {n} inputs"
)
# The endpoint may return rows out of order — sort by index, then
# require the indices to be exactly 0..n-1 so positional alignment is
# provably correct (a server using absolute or duplicate indices would
# otherwise pass the count check yet map vectors to the wrong texts).
try:
rows = sorted(rows, key=lambda d: d.get("index", -1))
indices = [r.get("index") for r in rows]View on GitHub (pinned to 06cb6987f0)
Solutions
- Curl the endpoint manually and confirm the body shape is a JSON object containing a 'data' array
- Point MEMPALACE_EMBEDDING_API_URL at a real OpenAI-compatible /v1/embeddings endpoint
- If writing a stub server, wrap results: {"data": [{"index": 0, "embedding": [...]}, ...]}
- Check for a proxy or gateway rewriting responses
Example fix
# stub server — before
return JsonResponse([{"index": 0, "embedding": vec}])
# after
return JsonResponse({"data": [{"index": 0, "embedding": vec}]}) Defensive patterns
Strategy: validation
Validate before calling
import json, urllib.request
def probe_embeddings_endpoint(url: str, model: str) -> bool:
payload = json.dumps({"model": model, "input": ["probe"], "encoding_format": "float"}).encode()
req = urllib.request.Request(url.rstrip('/') , data=payload, headers={"Content-Type": "application/json"})
with urllib.request.urlopen(req, timeout=10) as r:
return isinstance(json.loads(r.read()), dict) # must be a top-level object Type guard
def is_embeddings_response_shape(data) -> bool:
return isinstance(data, dict) and isinstance(data.get("data"), list) Try / catch
try:
vecs = ef(texts)
except EmbeddingAPIError as e:
if "non-object response" in str(e):
log.error("endpoint %s is not OpenAI-compatible", url) # config error: fix the URL
raise Prevention
- Point mempalace only at endpoints implementing POST /v1/embeddings
- Add a one-request probe at startup of your pipeline to fail fast
- When writing stub servers, return the full {"data": [...]} envelope
When it happens
Trigger: The configured openai-compat endpoint returns a JSON array, a plain string, or an error page parsed as JSON — e.g. pointing MEMPALACE_EMBEDDING_API_URL at a non-OpenAI REST service, a misrouted reverse proxy that returns a status payload, or a mock/stub server used in tests.
Common situations: URL points at the wrong API (e.g. a models list endpoint or a management API); a gateway (nginx traefik) returns a JSON status object on error paths; hand-rolled stub servers during development that return [{...}] instead of {"data": [...]}
Related errors
- Embedding API at {self._url} returned non-object rows: {e}
- Embedding API at {self._url} returned no 'data' array: {data
- Embedding API at {self._url} returned {len(rows)} embeddings
- Embedding API at {self._url} returned non-contiguous or dupl
- Embedding API at {self._url} returned malformed embeddings:
AI-assisted analysis of MemPalace/mempalace@06cb6987f0 (2026-08-15).
Data as JSON: /api/errors/55e39160e901cdcb.
Report an issue: GitHub.