affaan-m/ECC · error · anyhow::Error
{stderr}
Error message
{stderr} What it means
Same validation site as the generic invalid-ref error: when `validate_branch_name`'s underlying git check fails but git DOES print a message, the library bails with that raw `{stderr}`. So this error carries git's actual explanation, e.g. 'fatal: 'a..b' is not a valid branch name'.
Solutions
- Read the stderr in the error message — it names the exact rule violated
- Strip 'refs/heads/' or remote prefixes before validating ('name.rsplit_once("/")' is not enough; use the last segment)
- Remove invalid sequences like '..' and '@{' and re-validate
- Follow up with 'git check-ref-format' locally to confirm the sanitized name passes
Example fix
// before
let name = "feature/a..b";
validate_branch_name(&root, name)?;
// after
let name = name.trim_start_matches("refs/heads/").replace("..", "-");
validate_branch_name(&root, &name)?; Defensive patterns
Strategy: validation
Validate before calling
let check = Command::new("git")
.args(["check-ref-format", "--branch", name])
.output()?;
if !check.status.success() {
let msg = String::from_utf8_lossy(&check.stderr).trim().to_string();
anyhow::bail!("invalid branch name: {msg}");
} Type guard
fn is_valid_git_ref(name: &str) -> bool {
!name.trim_start_matches("refs/heads/").is_empty()
&& !name.contains("..")
&& !name.contains("@{")
&& !name.starts_with('/')
&& !name.ends_with('/')
&& !name.contains(" ")
} Try / catch
match validate_branch_name(&root, name) {
Ok(()) => (),
Err(e) => {
// error body is git's own stderr — surface it verbatim to the user
eprintln!("git rejected branch name: {e}");
return Err(e);
}
} Prevention
- Strip refs/heads/ and remote prefixes before validating names
- Pre-validate names with git check-ref-format so git's own message is shown
- Reject or transform '..' sequences from version-like inputs
- Log the raw name alongside the error for debugging config-driven names
When it happens
Trigger: Calling branch creation/validation with a name git explicitly rejects, where stderr is non-empty: forbidden sequences ('..'), leading/trailing slashes, 'refs/heads/' prefixes, reserved names.
Common situations: Names pasted with 'origin/' or 'refs/heads/' prefixes; branch names containing '..' from version-range strings; unicode or emoji names on filesystems that reject them.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- branch name is not a valid git ref
- commit message cannot be empty
- worktree_branch_prefix cannot be empty
- -32602
- a claim token is required
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/1803808d7b43da04.
Report an issue: GitHub.
Appendix: source
Thrown at ecc2/src/worktree/mod.rs:1493
Ok(String::from_utf8_lossy(&output.stdout).trim().to_string())
}
fn validate_branch_name(repo_root: &Path, branch: &str) -> Result<()> {
let output = Command::new("git")
.arg("-C")
.arg(repo_root)
.args(["check-ref-format", "--branch", branch])
.output()
.context("Failed to validate worktree branch name")?;
if output.status.success() {
Ok(())
} else {
let stderr = String::from_utf8_lossy(&output.stderr).trim().to_string();
if stderr.is_empty() {
anyhow::bail!("branch name is not a valid git ref");
} else {
anyhow::bail!("{stderr}");
}
}
}
fn parse_git_status_entry(line: &str) -> Option<GitStatusEntry> {
if line.len() < 4 {
return None;
}
let bytes = line.as_bytes();
let index_status = bytes[0] as char;
let worktree_status = bytes[1] as char;
let raw_path = line.get(3..)?.trim();
if raw_path.is_empty() {
return None;
}
let display_path = raw_path.to_string();
let normalized_path = raw_path
.split(" -> ")View on GitHub (pinned to 8321021c54)