gitbutlerapp/gitbutler · error
implement list and call recursively
Error message
implement list and call recursively
What it means
In crates/but/src/lib.rs dispatch_subcommand, the `but branch` command with no subcommand panics via todo!("implement list and call recursively") when the binary is built without the "legacy" feature. With the legacy feature, it delegates to command::legacy::branch::handle_no_subcommand instead.
Solutions
- Use `but branch list` explicitly, which avoids the no-subcommand arm.
- Build/install the CLI with the legacy feature enabled (cargo build --features legacy) to get the historical bare-branch behavior.
- Implement the non-legacy path in crates/but/src/lib.rs: list branches and recurse into the branch subcommand dispatch.
Example fix
// before but branch // after but branch list
Defensive patterns
Strategy: validation
Validate before calling
# shell guard before invoking if but branch --help 2>/dev/null | grep -q list; then but branch list else echo "bare 'but branch' unsupported on this build" fi
Prevention
- Always pass an explicit subcommand (`but branch list`) instead of relying on bare-command shorthands.
- Match your build's feature set: legacy builds allow `but branch` bare.
- Check `but --version` / build features in CI scripts.
When it happens
Trigger: Running `but branch` (no subcommand) on a non-legacy build — the cfg arm selects the todo!() and the CLI panics.
Common situations: Installing `but` from a build without the legacy feature and trying the bare `but branch` listing command; CI scripts relying on the legacy shorthand against a modern build.
Related errors
- BUG: It should not be possible to omit sources
- not yet implemented
- object for prefix exists
- swap connections of nodes as well
- the prefix is unambiguous
AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18).
Data as JSON: /api/errors/a6f0f529451ca8b7.
Report an issue: GitHub.
Appendix: source
Thrown at crates/but/src/lib.rs:1014
}
worktree::Subcommands::Unarchive { worktree } => {
let outcome = command::worktree::archive::set_archived(&ctx, &worktree, false)?;
out.print_cli_output(outcome)?;
}
worktree::Subcommands::Remove { force, worktree } => {
let outcome = command::worktree::remove::remove(&mut ctx, &worktree, force)?;
out.print_cli_output(outcome)?;
}
worktree::Subcommands::New { name } => {
let outcome = command::worktree::new::new(&mut ctx, name.as_ref())?;
out.print_cli_output(outcome)?;
}
}
None
}
Subcommands::Branch(branch::Platform { cmd }) => match cmd {
#[cfg(not(feature = "legacy"))]
None => todo!("implement list and call recursively"),
#[cfg(feature = "legacy")]
None => {
command::legacy::branch::handle_no_subcommand(&mut ctx, out)?;
None
}
#[cfg(feature = "legacy")]
Some(branch::Subcommands::List {
filter,
local,
remote,
all,
no_ahead,
review,
no_check,
empty,
}) => {
command::legacy::branch::list_branches(
&mut ctx, out, filter, local, remote, all, no_ahead, review, no_check, empty,View on GitHub (pinned to 58e5313667)