nikivdev/code · error
kimi returned empty review output (no text content in respon
Error message
kimi returned empty review output (no text content in response)
What it means
Thrown when kimi exits successfully with non-empty stdout, but after extracting the assistant text content from the stream-JSON response the resulting review text is empty — i.e. the response contained no usable 'text' content blocks.
Source
Thrown at src/commit.rs:6071
let stdout_text = String::from_utf8_lossy(&stdout_bytes);
let error_msg = if stderr_text.trim().is_empty() {
stdout_text.trim()
} else {
stderr_text.trim()
};
bail!("kimi review failed: {}", error_msg);
}
let stdout_text = String::from_utf8_lossy(&stdout_bytes).trim().to_string();
if stdout_text.is_empty() {
bail!("kimi returned empty output");
}
// Parse the stream-json output from kimi
// Format: {"role":"assistant","content":[{"type":"think","think":"..."},{"type":"text","text":"..."}]}
let result = extract_kimi_text_content(&stdout_text).unwrap_or_else(|| stdout_text.clone());
if result.is_empty() {
bail!("kimi returned empty review output (no text content in response)");
}
// Try to parse JSON from output
let mut review_json = parse_review_json(&result);
let future_tasks = review_json
.as_ref()
.map(|json| normalize_future_tasks(&json.future_tasks))
.unwrap_or_default();
let mut summary = review_json.as_ref().and_then(|r| r.summary.clone());
let quality = review_json.as_mut().and_then(|r| r.quality.take());
let (mut issues_found, mut issues) = if let Some(ref json) = review_json {
(json.issues_found, json.issues.clone())
} else {
let lowered = result.to_lowercase();
let has_issues = lowered.contains("bug")
|| lowered.contains("issue")
|| lowered.contains("error")
|| lowered.contains("problem")View on GitHub (pinned to a747e741ae)
Solutions
- Update the kimi CLI and retry — the stream-JSON schema may have changed relative to extract_kimi_text_content().
- Lower review scope/diff size to avoid truncation and encourage a text answer.
- Adjust review instructions/prompt to require a textual verdict.
- Check kimi raw output manually (run the command with the same flags) and report a parser bug if 'text' content exists but isn't extracted.
Defensive patterns
Strategy: type-guard
Validate before calling
fn has_text_content(stream_json: &str) -> bool {
serde_json::from_str::<serde_json::Value>(stream_json).ok()
.and_then(|v| v.get("content").cloned())
.and_then(|c| c.as_array().cloned())
.map(|blocks| blocks.iter().any(|b| b.get("type").and_then(|t| t.as_str()) == Some("text")
&& b.get("text").and_then(|t| t.as_str()).map(|s| !s.trim().is_empty()).unwrap_or(false)))
.unwrap_or(false)
} Type guard
fn extract_nonempty_text(v: &serde_json::Value) -> Option<&str> {
v.get("content")?.as_array()?
.iter()
.find_map(|b| {
let t = b.get("text")?.as_str()?;
(!t.trim().is_empty()).then_some(t)
})
} Try / catch
match run_kimi_review(&diff).await {
Err(e) if e.to_string().contains("empty review output") => {
eprintln!("kimi gave no text content; retrying with explicit instruction");
run_kimi_review(&format!("{diff}\n\nRespond with a textual review.")).await
}
other => other,
} Prevention
- Require a textual answer in review instructions/prompts
- Update kimi CLI in lockstep with parser expectations (extract_kimi_text_content)
- Add a parser regression test against real kimi stream-JSON samples
- Detect think-only responses early and re-prompt instead of failing at parse time
When it happens
Trigger: extract_kimi_text_content() on the stream-json stdout yields nothing (only 'think' blocks, no 'text' block) and the raw fallback is also empty after parsing.
Common situations: kimi model returned only reasoning/think content with no final answer; kimi response format changed in a newer CLI version, breaking the parser; truncated response due to token limits; unusual prompt producing no text output.
Related errors
- kimi review failed: {}
- kimi returned empty output
- No exchanges found in session
- AI returned an empty response.
- Could not parse AI response: '{}'
AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01).
Data as JSON: /api/errors/95fa09922a2b382e.
Report an issue: GitHub.