Aider-AI/aider · error · Exception
No data found in LLM response!
Error message
No data found in LLM response!
What it means
Raised in BaseCoder's response-processing path when BOTH attribute probes on the LLM completion message failed: completion.choices[0].message.tool_calls raised AttributeError AND completion.choices[0].message.content raised AttributeError. That means the chat completion object has neither tool calls nor textual content, so there is nothing to show or apply. It is a plain Exception (not a typed error), signalling an empty/malformed API response.
Source
Thrown at aider/coders/base_coder.py:1880
except AttributeError:
reasoning_content = None
try:
self.partial_response_content = completion.choices[0].message.content or ""
except AttributeError as content_err:
show_content_err = content_err
resp_hash = dict(
function_call=str(self.partial_response_function_call),
content=self.partial_response_content,
)
resp_hash = hashlib.sha1(json.dumps(resp_hash, sort_keys=True).encode())
self.chat_completion_response_hashes.append(resp_hash.hexdigest())
if show_func_err and show_content_err:
self.io.tool_error(show_func_err)
self.io.tool_error(show_content_err)
raise Exception("No data found in LLM response!")
show_resp = self.render_incremental_response(True)
if reasoning_content:
formatted_reasoning = format_reasoning_content(
reasoning_content, self.reasoning_tag_name
)
show_resp = formatted_reasoning + show_resp
show_resp = replace_reasoning_tags(show_resp, self.reasoning_tag_name)
self.io.assistant_output(show_resp, pretty=self.show_pretty())
if (
hasattr(completion.choices[0], "finish_reason")
and completion.choices[0].finish_reason == "length"
):
raise FinishReasonLength()View on GitHub (pinned to 5dc9490bb3)
Solutions
- Log the raw completion (self.verbose / print(completion)) to see which fields the provider actually returned.
- Verify provider compatibility: the endpoint must return OpenAI-shaped messages with content or tool_calls on choices[0].message.
- Retry the request — transient empty responses from proxies/self-hosted servers often succeed on resend.
- If using a custom LiteLLM/aider model mapping, check the model config (API base, model name) points at a truly OpenAI-compatible API.
- Upgrade aider and the openai SDK; schema handling of reasoning_content vs content changed across versions.
Example fix
# before
# rely on the raw exception
try:
coder.run_one(user_msg)
except Exception as e:
print(e) # "No data found in LLM response!"
# after
# inspect what the provider actually returns before blaming the prompt
completion = client.chat.completions.create(...)
msg = completion.choices[0].message
assert getattr(msg, "content", None) or getattr(msg, "tool_calls", None), completion.model_dump() Defensive patterns
Strategy: try-catch
Validate before calling
def completion_has_data(completion) -> bool:
try:
msg = completion.choices[0].message
except (IndexError, AttributeError):
return False
return bool(getattr(msg, "content", None)) or bool(getattr(msg, "tool_calls", None)) Type guard
def is_usable_completion(c) -> bool:
"""True if the completion carries content or tool calls."""
msgs = getattr(getattr(c, "choices", None) or [None], "__getitem__", lambda i: None)(0)
m = getattr(msgs, "message", None)
return bool(m) and (bool(getattr(m, "content", None)) or bool(getattr(m, "tool_calls", None))) Try / catch
try:
coder.send(new_message)
except Exception as e:
if str(e) == "No data found in LLM response!":
# empty/malformed provider response — safe to retry once, then report
coder.send(new_message)
else:
raise Prevention
- Smoke-test third-party OpenAI-compatible endpoints with a one-shot completion and assert content is present before starting a session.
- Enable coder.verbose to dump raw completions when integrating a new provider.
- Keep the openai SDK and aider versions aligned with the provider's schema; watch for proxies that strip message fields.
When it happens
Trigger: A chat completion arrives where choices[0].message lacks both 'content' and 'tool_calls' — typically from a non-OpenAI-compatible gateway, a response truncated by length limits, a content-filtered response, or a caching/mock layer returning a bare object. Also hit when the response represents only reasoning/abort fields with no message payload.
Common situations: Using an OpenAI-compatible proxy or local model server whose schema drifts from the OpenAI SDK (missing attributes); empty responses from content filters; streaming assembled into an incomplete message; bugs in custom LLM middleware or recorded-fixture replays in tests.
Related errors
- Unknown edit format {edit_format}. Valid formats are: {', '.
- # {len(failed)} SEARCH/REPLACE {blocks} failed to match!\n
- Bad/missing filename. The filename must be alone on the line
- Expected `=======`
- Expected `>>>>>>> REPLACE` or `=======`
AI-assisted analysis of Aider-AI/aider@5dc9490bb3 (2026-08-15).
Data as JSON: /api/errors/22068bbf27bbfe25.
Report an issue: GitHub.