GitoxideLabs/gitoxide · error
an empty commit needs a title
Error message
an empty commit needs a title
What it means
Thrown when an `empty` todo command yields no title. An `empty` step creates a commit without changes, which still requires a commit message; the title is taken from the command's value or falls back to the previous line's `tail`, and both being empty is invalid.
Solutions
- Provide a title after the `empty` command, e.g. `empty WIP checkpoint`
- Ensure the preceding line provides a usable `tail` if relying on the fallback
- Remove the `empty` line if no empty commit is needed
Example fix
// before empty // after empty add TODO notes
Defensive patterns
Strategy: validation
Validate before calling
for line in todo.lines() {
if let Some(verb) = line.split_whitespace().next() {
if verb == "empty" {
let title = line["empty".len()..].trim();
if title.is_empty() { anyhow::bail!("empty commit needs a title"); }
}
}
} Type guard
fn empty_line_has_title(line: &str) -> bool {
!line.strip_prefix("empty").map_or(false, str::trim)
.map_or(true, str::is_empty) || line.split_whitespace().count() > 1
} Try / catch
match parse_plan(...) {
Err(e) if e.to_string().contains("needs a title") => { /* supply a title for the empty line */ }
other => other?,
} Prevention
- Always write `empty <title>` with a non-empty title
- Do not rely on the tail fallback unless the previous line provides one
- Validate todo lines for a non-empty title before parsing
When it happens
Trigger: `parse_plan` reads `empty` (or `empty ` with only whitespace) on a line where the fallback `tail` is also empty.
Common situations: Writing a bare `empty` line in a todo intending a placeholder commit; scripted generation that forgets to include a title; trimming that stripped the intended 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
- an editable commit is not connected to the selected base
- the rebase todo contains more than one @ command
- the new commit would be empty; use new-empty instead
- lines in ' ' could not be parsed
- Invalid pathspec - path must not be empty, not be excluded…
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/da541762bc2bca5a.
Report an issue: GitHub.
Appendix: source
Thrown at gix-tix/src/edit/todo.rs:988
} else {
(resolve_commit(repo, value)?, false)
};
if !scope.contains(&id) {
anyhow::bail!("a pick is outside the editable history");
}
if picked.contains_key(&id) {
anyhow::bail!("a commit is picked more than once");
}
if resolved {
rebase::PlanCommit::Resolved(id)
} else {
rebase::PlanCommit::Pick(id)
}
}
"empty" => {
let title = if value.trim().is_empty() { tail } else { value.trim() };
if title.is_empty() {
anyhow::bail!("an empty commit needs a title");
}
rebase::PlanCommit::Empty(BString::from(title))
}
_ => anyhow::bail!("unsupported rebase todo command {verb:?}"),
};
let index = steps.len();
if let rebase::PlanCommit::Pick(id) | rebase::PlanCommit::Resolved(id) = commit {
picked.insert(id, index);
}
steps.push(rebase::PlanStep {
parent,
commit,
squash: Vec::new(),
});
cursor = Some(rebase::PlanParent::Step(index));
section_last_step = Some(index);
if marked {
let target = rebase::PlanParent::Step(index);View on GitHub (pinned to e73179060b)