MemPalace/mempalace · error · EmbeddingAPIError
Embedding API request to {self._url} failed: {e}. Check that
Error message
Embedding API request to {self._url} failed: {e}. Check that the server is reachable and MEMPALACE_EMBEDDING_API_URL / embedding_api_url is correct. What it means
Raised by the OpenAI-compatible embedding client when the HTTP POST to self._url fails at the transport layer. It catches a deliberately wide net — HTTPError, URLError, OSError, http.client.HTTPException, and ValueError (invalid URL scheme or JSON decode of the response body) — because local/self-hosted servers (LM Studio, llama.cpp, vLLM, Ollama) commonly produce low-level protocol faults. The message names the URL and both config surfaces (MEMPALACE_EMBEDDING_API_URL env var / embedding_api_url in ~/.mempalace/config.json) so the user can correct the endpoint.
Source
Thrown at mempalace/embedding.py:558
if self._api_key:
headers["Authorization"] = f"Bearer {self._api_key}"
out: list = []
texts = list(input)
for start in range(0, len(texts), _EF_API_BATCH):
batch = texts[start : start + _EF_API_BATCH]
# encoding_format=float is explicit so a server that defaults to
# base64 doesn't hand back strings we'd mis-parse as vectors.
payload = {"model": self._model, "input": batch, "encoding_format": "float"}
req = Request(self._url, data=json.dumps(payload).encode("utf-8"), headers=headers)
try:
with urlopen(req, timeout=_EF_API_TIMEOUT) as resp:
data = json.loads(resp.read())
# ValueError covers an invalid/missing URL scheme and json.JSONDecodeError;
# http.client.HTTPException covers low-level protocol faults (BadStatusLine,
# IncompleteRead) common with local/overloaded servers.
except (HTTPError, URLError, OSError, http.client.HTTPException, ValueError) as e:
raise EmbeddingAPIError(
f"Embedding API request to {self._url} failed: {e}. Check that the "
f"server is reachable and MEMPALACE_EMBEDDING_API_URL / embedding_api_url "
f"is correct."
) 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.
"""View on GitHub (pinned to 06cb6987f0)
Solutions
- Verify the server is up: curl -s http://host:port/v1/embeddings -d '{"model":"x","input":["hi"]}' -H 'Content-Type: application/json'
- Check the configured URL matches the server's embeddings endpoint, including scheme and port: MEMPALACE_EMBEDDING_API_URL=http://127.0.0.1:1234 (must include http://)
- If the server was slow to start (first model load), wait for it to finish loading and retry
- Disable proxying for localhost if a corporate proxy is set: export NO_PROXY=localhost,127.0.0.1
- For IncompleteRead/BadStatusLine under load, reduce concurrent mempalace operations or raise the server's worker capacity
Example fix
# before
export MEMPALACE_EMBEDDING_API_URL=127.0.0.1:1234 # missing scheme -> ValueError path
# after
export MEMPALACE_EMBEDDING_API_URL=http://127.0.0.1:1234
# retry wrapper
from mempalace.embedding import EmbeddingAPIError
try:
vecs = ef(texts)
except EmbeddingAPIError as e:
if 'failed' in str(e):
time.sleep(2); vecs = ef(texts) # server still warming up Defensive patterns
Strategy: retry
Validate before calling
import socket
from urllib.parse import urlparse
def endpoint_reachable(url: str, timeout: float = 2.0) -> bool:
u = urlparse(url)
if u.scheme not in ("http", "https") or not u.hostname:
return False
with socket.socket() as s:
s.settimeout(timeout)
return s.connect_ex((u.hostname, u.port or (443 if u.scheme == 'https' else 80))) == 0 Try / catch
from mempalace.embedding import EmbeddingAPIError
import time
for attempt in range(3):
try:
vecs = ef(texts)
break
except EmbeddingAPIError as e:
if attempt == 2 or "non-object" in str(e) or "malformed" in str(e):
raise # only retry transport faults, not schema errors
time.sleep(2 ** attempt) # server may still be loading its model Prevention
- Health-check the embedding server before starting bulk ingest
- Always include the scheme in MEMPALACE_EMBEDDING_API_URL (http://...)
- Set NO_PROXY=localhost,127.0.0.1 when a corporate proxy is present
- Give local servers time to load the model on first request; warm them with a one-text request
When it happens
Trigger: embedding_model='openai-compat' is configured and the server is down, the URL has a typo or wrong port, the URL lacks a scheme (ValueError path), the server returns non-JSON over HTTP 200, or the server drops the connection mid-response (IncompleteRead) under load. Timeout is _EF_API_TIMEOUT, so a hung server also lands here.
Common situations: LM Studio or Ollama not started before running mempalace; pointing at the chat completions port instead of the embeddings port; using https:// against a plain-HTTP local server; corporate proxies intercepting localhost; server overloaded so reads time out; URL configured as 'host:port' without http://.
Related errors
- HTTP {e.code} from {url}: {detail or e.reason}
- Embedding API at {self._url} returned a non-object response:
- 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-object rows: {e}
AI-assisted analysis of MemPalace/mempalace@06cb6987f0 (2026-08-15).
Data as JSON: /api/errors/5906bebd953bbae2.
Report an issue: GitHub.