theonedev/onedev · error · ExplicitException
Received empty response
Error message
Received empty response
What it means
The chat runner waits for the LLM response future with a timeout; if the eventual response string is blank/whitespace, the service treats it as an unusable model output and throws this ExplicitException instead of creating an empty chat response.
Source
Thrown at server-core/src/main/java/io/onedev/server/ai/DefaultChatService.java:468
if (requests.size() == 1) {
var prompt = "Summarize below message as a compact title (only title, no comments or other text): \n\n" + requests.get(0).getContent();
var title = chatModel.chat(new UserMessage(prompt)).aiMessage().text();
if (StringUtils.isNotBlank(title)) {
if (anonymous) {
chat = SerializationUtils.clone(chat);
chat.setTitle(title);
session.getAnonymousChats().put(chatId, chat);
} else {
chat.setTitle(title);
dao.persist(chat);
}
webSocketService.notifyObservableChange(Chat.getChangeObservable(chatId), null);
}
}
});
var response = responseFuture.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
if (StringUtils.isBlank(response))
throw new ExplicitException("Received empty response");
createResponse(response, false);
} catch (Throwable t) {
if (ExceptionUtils.find(t, InterruptedException.class) != null) {
createIncompleteResponse("Conversation cancelled");
} else if (ExceptionUtils.find(t, TimeoutException.class) != null) {
createIncompleteResponse("Conversation timed out");
} else {
var explicitException = ExceptionUtils.find(t, ExplicitException.class);
if (explicitException != null) {
createResponse(explicitException.getMessage(), true);
} else {
createResponse("Error getting chat response, check server log for details", true);
logger.error("Error getting chat response", t);
}
}
} finally {
responseFuture.cancel(false);
var respondingsOfSession = respondings.get(sessionId); View on GitHub (pinned to d44925c47c)
Solutions
- Retry the conversation — empty completions are often transient model/provider behavior
- Check the configured AI provider endpoint, API key, and model name; test the provider directly
- Inspect the prompt/messages sent — remove inputs that yield no content (e.g. only system instructions)
- Check provider-side logs for content-filter or truncation flags on the request
Example fix
// before: response comes back blank
// after: caller guards and retries once on empty response
try {
chatService.chat(chatId, prompt);
} catch (ExplicitException e) {
if ("Received empty response".equals(e.getMessage())) {
retryWithBackoff(chatId, prompt, 1);
}
} Defensive patterns
Strategy: retry
Validate before calling
// verify provider works before chatting
def provider_ok():
r = requests.post(MODEL_URL, headers=auth, json=ping_payload)
return r.status_code == 200 and r.text.strip() != "" Try / catch
try {
chatService.chat(chatId, prompt);
} catch (ExplicitException e) {
if ("Received empty response".equals(e.getMessage())) {
retryWithBackoff(chatId, prompt);
}
} Prevention
- Retry transient empty completions with backoff
- Verify AI provider endpoint, key, and model configuration
- Avoid prompts that can elicit no content (e.g. only tool calls)
- Check provider content-filter flags when empty responses recur
When it happens
Trigger: responseFuture.get(TIMEOUT_SECONDS, SECONDS) resolves but StringUtils.isBlank(response) is true — the model returned an empty completion (e.g. content filtered or empty stream).
Common situations: LLM provider returning empty completions due to content filters; misconfigured model endpoint returning empty bodies; prompt consisting only of tool calls with no final content; provider outage degrading responses.
Understand the failure class
Background: "empty response", "returned no data", "empty embeddings": what HTTP 200-with-empty-body errors mean across libraries — this error's family across 36 libraries.
Related errors
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/94556838d697e88b.
Report an issue: GitHub.