MemPalace/mempalace · error · LLMError

Empty response from Ollama (model={self.model})

Error message

Empty response from Ollama (model={self.model})

What it means

LLMError raised by OllamaProvider.classify() when the /api/chat response parses but message.content is missing or empty. Ollama returns HTTP 200 with an empty content field in several edge cases, so the provider treats empty output as a hard failure rather than returning ''.

Source

Thrown at mempalace/llm_client.py:270

            "messages": [
                {"role": "system", "content": system},
                {"role": "user", "content": user},
            ],
            "stream": False,
            "options": options,
        }
        if json_mode:
            body["format"] = "json"
        if think is not None:
            # Ollama 0.7+ supports `think` for thinking-capable models (Qwen 3
            # family, DeepSeek-R1). Pure-instruct models ignore it. We forward
            # only when the caller explicitly opts in/out so the wire format
            # stays minimal for the common case.
            body["think"] = think
        data = _http_post_json(f"{self.endpoint}/api/chat", body, headers={}, timeout=self.timeout)
        text = (data.get("message") or {}).get("content", "")
        if not text:
            raise LLMError(f"Empty response from Ollama (model={self.model})")
        return LLMResponse(text=text, model=self.model, provider=self.name, raw=data)


# ==================== OPENAI-COMPAT ====================


class OpenAICompatProvider(LLMProvider):
    """Any OpenAI-compatible ``/v1/chat/completions`` endpoint.

    Supply ``--llm-endpoint http://host:port`` (with or without ``/v1``).
    API key via ``--llm-api-key`` or the ``OPENAI_API_KEY`` env var.
    """

    name = "openai-compat"

    def __init__(
        self,
        model: str,

View on GitHub (pinned to 06cb6987f0)

Solutions

  1. Reproduce with `ollama run <model>` and the same prompt to see what the model actually emits
  2. For thinking models, pass think explicitly or increase the response budget so a final answer is produced
  3. Try a stronger instruct model (e.g. llama3.1/qwen2.5 instruct tags) for classification
  4. Disable json_mode to check whether format constraints are suppressing output

Example fix

# before
resp = provider.classify(system, user, json_mode=True)  # Empty response from Ollama (model=qwen3:8b)

# after
resp = provider.classify(system, user, json_mode=True, think=False)  # force a direct answer
Defensive patterns

Strategy: retry

Validate before calling

ok, reason = provider.check_available()
if not ok:
    raise RuntimeError(f"Ollama not ready: {reason}")

Try / catch

from mempalace.llm_client import LLMError

for attempt in range(2):
    try:
        return provider.classify(system, user, json_mode=True, think=False)
    except LLMError as e:
        if "Empty response" in str(e) and attempt == 0:
            continue
        raise

Prevention

When it happens

Trigger: Calling classify() with json_mode=True on a model that emits nothing but a think block (thinking models with think enabled and no final answer); a model that responds entirely via tool_calls; content genuinely empty because the prompt produced no tokens.

Common situations: Using Qwen3/DeepSeek-R1 style models where `think` is forwarded and the model spends the whole budget reasoning; num_ctx too small so the model degenerates; wrong tag pulled (a model that answers in an unexpected field); json mode on a model with weak instruction following.

Related errors


AI-assisted analysis of MemPalace/mempalace@06cb6987f0 (2026-08-15). Data as JSON: /api/errors/1c73bf3ff8fba7a0. Report an issue: GitHub.