gitbutlerapp/gitbutler · error

commit message cannot be empty

Error message

commit message cannot be empty

What it means

but_action::reword::commit bails with "commit message cannot be empty" when the (RFC-formatted) commit message passed as input is empty. A reword requires a non-empty message because a commit cannot have an empty message.

Solutions

  1. Provide a non-empty message in the input before calling commit().
  2. Validate the message at the caller/UI layer and prompt again if empty after trimming.
  3. Skip the reword operation (keep the existing message) when no new message is supplied.

Example fix

// before
commit(ws, input_with_empty_message).await?;
// after
if input.message.trim().is_empty() {
    anyhow::bail!("provide a commit message"); // or reuse the old message
}
commit(ws, input).await?;
Defensive patterns

Strategy: validation

Validate before calling

if !input.message.trim().is_empty() {
    // safe to call
}

Type guard

fn has_message(m: &str) -> bool { !m.trim().is_empty() }

Try / catch

match commit(ws, input).await {
    Err(e) if e.to_string().contains("commit message cannot be empty") => { /* re-prompt or keep old message */ }
    r => r?,
}

Prevention

When it happens

Trigger: Calling but_action reword commit with input whose `message` field is empty or whitespace-only, so format_commit_message yields an empty string and the bail! fires at crates/but-action/src/reword.rs:42.

Common situations: An agent/automation sends an empty reword message; a user confirms the message editor without typing anything; trimming strips all content from a placeholder message.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18). Data as JSON: /api/errors/452f9be46988b39d. Report an issue: GitHub.

Appendix: source

Thrown at crates/but-action/src/reword.rs:42

    meta: &mut impl RefMetadata,
    db: &mut but_db::DbHandle,
    context_lines: u32,
) -> anyhow::Result<(gix::ObjectId, String)> {
    let changes =
        but_core::diff::ui::commit_changes_with_line_stats_by_worktree_dir(repo, input.commit_id)?;
    let diff = changes.try_to_unidiff(repo, context_lines)?.to_string();
    let message = crate::generate::commit_message(
        llm,
        &input.external_summary,
        &input.external_prompt,
        &diff,
    )?;

    // Format the commit message to follow email RFC format (80 char line wrapping)
    let message = crate::commit_format::format_commit_message(&message);

    if message.is_empty() {
        bail!("commit message cannot be empty");
    }

    let editor = Editor::create(ws, meta, repo, db)?;
    let (rebase, edited_commit_selector) =
        but_workspace::commit::reword(editor, input.commit_id, message.as_bytes().as_bstr())?;
    let new_commit_id = rebase.lookup_pick(edited_commit_selector)?;
    rebase.materialize(Default::default())?;

    Ok((new_commit_id, message))
}

View on GitHub (pinned to 58e5313667)