MemPalace/mempalace · error · LLMError

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

Error message

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

What it means

LLMError raised by AnthropicProvider.classify() when the /v1/messages response contains content blocks but joining all type=='text' blocks yields an empty string — e.g. the response consists solely of tool_use or thinking blocks.

Source

Thrown at mempalace/llm_client.py:435

            "temperature": 0.1,
            "system": sys_prompt,
            "messages": [{"role": "user", "content": user}],
        }
        headers = {
            "X-API-Key": self.api_key,
            "anthropic-version": self.API_VERSION,
        }
        data = _http_post_json(
            f"{self.endpoint}/v1/messages", body, headers=headers, timeout=self.timeout
        )
        try:
            text = "".join(
                b.get("text", "") for b in data.get("content", []) or [] if b.get("type") == "text"
            )
        except (AttributeError, TypeError) as e:
            raise LLMError(f"Unexpected response shape: {e}") from e
        if not text:
            raise LLMError(f"Empty response from Anthropic (model={self.model})")
        return LLMResponse(text=text, model=self.model, provider=self.name, raw=data)


# ==================== FACTORY ====================


PROVIDERS: dict[str, type[LLMProvider]] = {
    "ollama": OllamaProvider,
    "openai-compat": OpenAICompatProvider,
    "anthropic": AnthropicProvider,
}


def get_provider(
    name: str,
    model: str,
    endpoint: Optional[str] = None,
    api_key: Optional[str] = None,

View on GitHub (pinned to 06cb6987f0)

Solutions

  1. Inspect raw response (LLMResponse.raw / provider debug) to see which block types came back
  2. If tool_use came back, adjust the prompt to request a direct textual answer
  3. Increase max_tokens so thinking models still produce a text block
  4. Retry once — occasional empty text turns are transient
Defensive patterns

Strategy: retry

Try / catch

from mempalace.llm_client import LLMError

for attempt in range(2):
    try:
        return provider.classify(s, u)
    except LLMError as e:
        if "Empty response from Anthropic" in str(e) and attempt == 0:
            continue
        raise

Prevention

When it happens

Trigger: A model turn that is entirely a tool_use block with no text; extended thinking consuming the whole response; a text block present but empty after filtering by type.

Common situations: Prompts that induce tool calling when the caller wanted prose; thinking-enabled models under max_tokens=2048 spending it all on reasoning; mismatched prompt format causing the model to emit only non-text blocks.

Related errors


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