refactor(errors): route git-plumbing failure bails through CommandError#3474
Merged
Conversation
Eight sites turned a captured non-zero exit into bail!("…{stderr}"),
bypassing CommandError::from_failed_output — the one constructor that
normalizes \r and gives renderers the typed command/output split. Convert
them: resolve_git_common_dir, the bulk config --list read, config --unset,
config --get-regexp, merge-tree, merge-base, the untracked-diff numstat,
and llm.rs run_git_capture (which now builds the Cmd itself so it can name
the args). from_failed_output takes &[impl AsRef<str>] so Vec<String>
arg lists work.
generate_commit_message now wraps only the execute_llm_command failure in
LlmCommandFailed, mirroring generate_squash_message — a git failure while
building the prompt is not an LLM-command failure, and flattening it into
LlmCommandFailed.error dropped the typed stderr.
Rendering: wrapped failures (context + CommandError) render identically;
bare ones gain the standard 'git … failed (exit N)' header + gutter. The
wt list task-failure lines for merge-base errors drop the hand-rolled
'git merge-base failed for <sha> <sha>:' prefix and now match their
sibling lines (bare stderr), per the updated snapshots.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
worktrunk-bot
approved these changes
Jul 15, 2026
worktrunk-bot
left a comment
Collaborator
There was a problem hiding this comment.
Correct, behavior-preserving refactor — every converted path now routes failed-command display through the single from_failed_output constructor, and the direct-test coverage on each is thorough. One optional micro-nit inline; nothing blocking.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #3459. Eight git-plumbing sites turned a captured non-zero exit into
bail!("…{stderr}"), bypassingCommandError::from_failed_output— the one constructor that normalizes\rand gives renderers the typed command/output split. This converts them (resolve_git_common_dir, the bulkconfig --listread,config --unset,config --get-regexp,merge-tree,merge-base, the untracked-diff numstat, andllm.rs::run_git_capture), so failed-command display routes through one constructor and themain.rsmultiline-error tripwire has nothing left to catch on these paths.from_failed_outputnow takes&[impl AsRef<str>]soVec<String>arg lists work.One structural fix rode along:
generate_commit_messagenow wraps only theexecute_llm_commandfailure inGitError::LlmCommandFailed, mirroringgenerate_squash_message— a git failure while building the prompt is not an LLM-command failure, and flattening it intoLlmCommandFailed.errordropped the typed stderr.Rendering: context-wrapped failures render byte-identically (the outside-repo snapshots pass untouched); bare ones gain the standard
git … failed (exit N)header + gutter. The only snapshot changes are twowt listtask-failure lines where merge-base errors drop the hand-rolledgit merge-base failed for <sha> <sha>:prefix and now match their sibling lines.Every converted error path has a direct test — five new ones using empirically-probed failure modes (invalid regexp pattern → exit 6, invalid key → exit 1, corrupt config → 128 for the lazily-populated bulk read and merge-tree, unborn HEAD for the numstat), plus the updated
run_git_captureunit test;resolve_git_common_dirandmerge_basewere already covered by existing snapshots.Two same-pattern sites remain in the commands layer (
step/shared.rsls-files,step/commit.rsstage-to-temp-index) — deliberately left for a follow-up along with the non-git CLIs (gh/glab, claude/codex).