GitoxideLabs/gitoxide · error

the edited commit message is empty

Error message

the edited commit message is empty

What it means

After the user saves the editor, `apply_conflict_reporting` parses the edited document and refuses to continue if the resulting commit message is empty. Rewording to an empty message is not allowed, so the reword/apply step is aborted with this error before any commit is rewritten.

Solutions

  1. Re-run the reword and keep at least a non-empty summary line in the editor before saving.
  2. If comments were stripped unintentionally, check the editor's comment character handling (CommentChar lines are ignored, not kept as message).
  3. Abort the reword if an empty message was intended — this operation cannot produce an empty commit message.
  4. In scripted flows, validate the message buffer is non-empty before invoking `apply`.

Example fix

// before
apply(repo, state, edited_bytes)?;
// after
if cleanup_message(edited_bytes, None).is_empty() {
    anyhow::bail!("reword aborted: message must not be empty");
}
apply(repo, state, edited_bytes)?;
Defensive patterns

Strategy: validation

Validate before calling

fn edited_message_nonempty(edited: &[u8]) -> bool {
    edited.iter().any(|&b| b != b'\n' && b != b'\r' && b != b' ' && b != b'\t')
}

Try / catch

match apply(repo, state, edited) {
    Ok(perform) => perform,
    Err(e) if e.to_string().contains("edited commit message is empty") => {
        eprintln!("Reword aborted: keep at least one summary line in the editor.");
        revert_to_pre_edit_state(state)
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling `apply_conflict_reporting` (from `apply`) with an `edited` buffer whose parsed `edit.message` is empty — i.e. the user cleared the message in the editor, or the editor saved only comment/todo lines that were stripped by `parse`/`cleanup_message`.

Common situations: A developer opens the reword editor, deletes the entire message (or all non-comment lines) and saves; an editor or script truncates the file; an automated flow pipes an empty message buffer into apply.

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 GitoxideLabs/gitoxide@e73179060b (2026-09-08). Data as JSON: /api/errors/e88f113ff0075396. Report an issue: GitHub.

Appendix: source

Thrown at gix-tix/src/edit/reword.rs:163

    repo: gix::Repository,
    graph: &crate::history::HistoryGraph,
    old_id: gix::ObjectId,
    edited: &[u8],
) -> Result<Outcome> {
    apply_conflict_reporting(repo, graph, old_id, edited, |_| {})?.complete()
}

#[tracing::instrument(skip_all, fields(commit_id = %old_id))]
pub(crate) fn apply_conflict_reporting(
    repo: gix::Repository,
    graph: &crate::history::HistoryGraph,
    old_id: gix::ObjectId,
    edited: &[u8],
    mut report: impl FnMut(rebase::Progress),
) -> Result<Perform> {
    let edit = parse(edited)?;
    if edit.message.is_empty() {
        anyhow::bail!("the edited commit message is empty");
    }

    let mut commit = repo
        .find_commit(old_id)
        .context("could not find commit after editing")?
        .decode()
        .context("could not decode commit after editing")?
        .into_owned()
        .context("could not own commit after editing")?;
    let author = actor(edit.author, edit.author_time, "author")?;
    let commit_changed = author != commit.author || edit.message != commit.message;
    let (rebased, enrichment, enrich_change) = if commit_changed {
        commit.author = author;
        commit.committer = actor(edit.committer, edit.committer_time, "committer")?;
        commit.message = edit.message;
        let (performed, enrichment) =
            apply_commit_conflict_with_enrichment(&repo, graph, old_id, commit, &edit.enrichment, &mut report)?;
        let outcome = match performed {

View on GitHub (pinned to e73179060b)