affaan-m/ECC · error · anyhow::Error
branch name is not a valid git ref
Error message
branch name is not a valid git ref
What it means
`validate_branch_name` runs git's own ref-name check and bails with this generic message when the check fails and git printed no stderr. It means the supplied branch name violates git ref naming rules (e.g. contains spaces, '..', starts with '-', ends with '.lock', or includes control characters).
Solutions
- Sanitize the name: replace spaces and invalid characters with '-', strip leading '-' and trailing '.lock'/'.'
- Validate before calling using 'git check-ref-format --branch <name>' and surface its stderr
- Keep names to [A-Za-z0-9._/-] without '..' or '@{' sequences
- If the name comes from user input, apply a slugify/kebab-case step at the boundary
Example fix
// before: raw user input
let branch = user_input.trim();
validate_branch_name(&root, branch)?;
// after: normalize to a safe ref name
let branch: String = user_input
.trim()
.to_lowercase()
.chars()
.map(|c| if c.is_ascii_alphanumeric() || matches!(c, '/' | '-' | '_' | '.') { c } else { '-' })
.collect();
let branch = branch.trim_matches(|c| c == '-' || c == '.').to_string();
validate_branch_name(&root, &branch)?; Defensive patterns
Strategy: validation
Validate before calling
let valid = Command::new("git")
.args(["check-ref-format", "--branch", name])
.output()
.map(|o| o.status.success())
.unwrap_or(false); Type guard
fn is_safe_branch_name(name: &str) -> bool {
!name.is_empty()
&& name.chars().all(|c| c.is_ascii_alphanumeric() || matches!(c, '/' | '-' | '_' | '.'))
&& !name.contains("..")
&& !name.contains("@{")
&& !name.starts_with('-')
&& !name.ends_with(".lock")
} Try / catch
match create_branch(&root, name) {
Ok(b) => b,
Err(e) if e.to_string().contains("not a valid git ref") => {
eprintln!("sanitize name '{name}' (spaces/.. /.lock are forbidden)");
return Err(e);
}
Err(e) => return Err(e),
} Prevention
- Slugify user- or AI-supplied names before creating branches
- Ban spaces, '..', '@{', leading '-', and '.lock' suffixes at input boundaries
- Validate with 'git check-ref-format --branch' before the create call
- Prefer kebab-case naming conventions for generated branch names
When it happens
Trigger: Creating or renaming a branch with a name git rejects but whose rejection message is empty — commonly names with forbidden sequences like 'a..b', 'a b', '@{', or empty/whitespace names.
Common situations: Branch name derived from a free-text prompt, ticket title, or AI-generated label that contains spaces or invalid characters; trailing slashes; names ending in '.lock' or '.".',
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
- {stderr}
- 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/687e9ae8f20faf76.
Report an issue: GitHub.
Appendix: source
Thrown at ecc2/src/worktree/mod.rs:1491
}
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();View on GitHub (pinned to 8321021c54)