unclecode/crawl4ai · error · ValueError

LLM returned an empty response

Error message

LLM returned an empty response

What it means

Raised in the generate_schema LLM loop when the completion returns choices[0].message.content that is empty or whitespace-only. Before JSON parsing, the code rejects blank responses as a ValueError — an empty completion is treated as a hard failure rather than retried in the same attempt cycle.

Source

Thrown at crawl4ai/extraction_strategy.py:1931

        for attempt in range(max_attempts):
            try:
                response = await aperform_completion_with_backoff(
                    provider=llm_config.provider,
                    prompt_with_variables=prompt,
                    json_response=True,
                    api_token=llm_config.api_token,
                    base_url=llm_config.base_url,
                    messages=messages,
                    extra_args=kwargs,
                )
                if usage is not None:
                    usage.completion_tokens += response.usage.completion_tokens
                    usage.prompt_tokens += response.usage.prompt_tokens
                    usage.total_tokens += response.usage.total_tokens
                raw = response.choices[0].message.content
                if not raw or not raw.strip():
                    raise ValueError("LLM returned an empty response")

                schema = json.loads(_strip_markdown_fences(raw))
                last_schema = schema
            except json.JSONDecodeError as e:
                # JSON parse failure — ask LLM to fix it
                if not validate or attempt >= max_attempts - 1:
                    raise Exception(f"Failed to parse schema JSON: {str(e)}")
                messages.append({"role": "assistant", "content": raw})
                messages.append({"role": "user", "content": (
                    f"Your response was not valid JSON. Parse error: {e}\n"
                    "Please return ONLY valid JSON, nothing else."
                )})
                continue
            except Exception as e:
                raise Exception(f"Failed to generate schema: {str(e)}")

            # If validation is off, return immediately (zero overhead path)
            if not validate:

View on GitHub (pinned to 7e80152142)

Solutions

  1. Verify the same prompt works with a direct LLM call using your llm_config credentials
  2. Check provider/base_url in LLMLConfig — an empty content often means you hit the wrong endpoint
  3. Try a different model or provider to rule out model-specific empty-response behavior
  4. Catch the ValueError and retry generate_schema — transient empty completions do occur

Example fix

// before
schema = await JsonElementExtractionStrategy.generate_schema(
    html=html, llm_config=LLMConfig(provider="local/empty-server"))
# ValueError: LLM returned an empty response

// after
for attempt in range(3):
    try:
        schema = await JsonElementExtractionStrategy.generate_schema(
            html=html, llm_config=LLMConfig(provider="openai/gpt-4o", api_token=tok))
        break
    except ValueError as e:
        if "empty response" not in str(e) or attempt == 2:
            raise
Defensive patterns

Strategy: retry

Validate before calling

# verify the LLM endpoint returns non-empty JSON-style completions first
from crawl4ai import aperform_completion_with_backoff  # or your provider SDK
resp = await aperform_completion_with_backoff(
    provider=cfg.provider, api_token=cfg.api_token,
    prompt='Reply with the single word: OK')
assert resp.choices[0].message.content.strip(), "endpoint returns empty content"

Try / catch

import asyncio

for i in range(3):
    try:
        schema = await JsonElementExtractionStrategy.generate_schema(html=h, llm_config=cfg)
        break
    except ValueError as e:
        if "empty response" not in str(e) or i == 2:
            raise
        await asyncio.sleep(2 ** i)

Prevention

When it happens

Trigger: The configured LLM endpoint returns an empty message: content-filtered responses, misconfigured local/OpenAI-compatible servers, token limits collapsing output to nothing, or a provider returning only whitespace.

Common situations: Using a local/incompatible OpenAI-compatible server whose response shape yields empty content; content-filtered or safety-blocked completions; API quota issues returning empty bodies; wrong base_url routing to a non-chat endpoint.

Related errors


AI-assisted analysis of unclecode/crawl4ai@7e80152142 (2026-08-14). Data as JSON: /api/errors/81b09593982c5bde. Report an issue: GitHub.