nikivdev/code · error
claude returned empty commit message
Error message
claude returned empty commit message
What it means
Thrown when the `claude` CLI exits successfully but its stdout, after trimming, is empty — no commit message was produced. The code deliberately distinguishes this from a process failure to give a clearer message.
Source
Thrown at src/commit.rs:12762
if !status.is_empty() {
prompt.push_str("\n\nGit status:\n");
prompt.push_str(status);
}
let output = Command::new("claude")
.args(["-p", &prompt])
.output()
.context("failed to run claude for commit message")?;
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr);
bail!("claude failed: {}", stderr.trim());
}
let message = String::from_utf8_lossy(&output.stdout).trim().to_string();
if message.is_empty() {
bail!("claude returned empty commit message");
}
Ok(trim_quotes(&message))
}
/// Generate commit message using Rise daemon (local AI proxy).
fn generate_commit_message_rise(
diff: &str,
status: &str,
truncated: bool,
model: &str,
) -> Result<String> {
let mut user_prompt =
String::from("Write a git commit message for the staged changes.\n\nGit diff:\n");
user_prompt.push_str(diff);
if truncated {
user_prompt.push_str("\n\n[Diff truncated]");View on GitHub (pinned to a747e741ae)
Solutions
- Run `claude -p "say hi"` and confirm it prints text to stdout.
- Re-authenticate with `claude login`.
- Check for shell aliases/wrappers intercepting claude output (`type claude`).
- Retry with a smaller diff/staged change set in case the model returned empty on a huge prompt.
Example fix
// before
if message.is_empty() {
bail!("claude returned empty commit message");
}
// after
if message.is_empty() {
bail!("claude returned empty commit message (stderr: {})", String::from_utf8_lossy(&output.stderr).trim());
} Defensive patterns
Strategy: fallback
Validate before calling
// Preflight: confirm claude produces non-empty stdout
let out = std::process::Command::new("claude").args(["-p", "ping"]).output()?;
if String::from_utf8_lossy(&out.stdout).trim().is_empty() {
return Err(anyhow!("claude CLI produces empty output"));
} Type guard
fn is_non_empty_message(s: &str) -> bool { !s.trim().is_empty() } Try / catch
match result {
Err(e) if e.to_string().contains("empty commit message") => {
eprintln!("claude returned nothing; check auth/alias, falling back");
fallback_to_manual_message()
}
other => other,
} Prevention
- Avoid shell aliases/wrappers around `claude` that swallow stdout.
- Re-authenticate when stderr shows warnings but exit code is 0.
- Cap diff size in the prompt so the model doesn't return empty on huge inputs.
- Configure a fallback provider for empty responses.
When it happens
Trigger: `claude -p <prompt>` exits 0 but prints nothing: silent auth degradation, output redirected elsewhere, model refusal producing no text, or stdout swallowed by a wrapper/alias.
Common situations: A shell alias or wrapper around `claude` consumes stdout; claude session expired so it warns on stderr but exits 0; model returns an empty response on a very large diff prompt.
Related errors
- claude failed: {}
- Rise daemon returned empty commit message
- OpenRouter returned empty commit message
- OpenAI returned empty commit message
- Missing profile: {}
AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01).
Data as JSON: /api/errors/6e31b0bc5e39129d.
Report an issue: GitHub.