nikivdev/code · error · anyhow::Error
git config --global --unset-all {} failed
Error message
git config --global --unset-all {} failed What it means
git_config_unset_all runs `git config --global --unset-all <key> <value>` (used by remove_url_rewrite to delete matching multi-valued entries) and bails if git exits nonzero. Note git also exits nonzero when the key/value is simply not present, so a no-op cleanup can surface as this error.
Source
Thrown at src/ssh.rs:485
.args(["config", "--global", "--add", key, value])
.status()
.context("failed to run git config")?;
if !status.success() {
anyhow::bail!("git config --global --add {} failed", key);
}
Ok(())
}
fn git_config_unset_all(key: &str, value: &str) -> Result<()> {
let status = Command::new("git")
.args(["config", "--global", "--unset-all", key, value])
.status()
.context("failed to run git config")?;
if !status.success() {
anyhow::bail!("git config --global --unset-all {} failed", key);
}
Ok(())
}
fn add_url_rewrite(key: &str, desired: &[&str]) -> Result<bool> {
let existing = git_config_get_all(key)?;
let mut changed = false;
for value in desired {
if existing.iter().any(|val| val == value) {
continue;
}
git_config_add(key, value)?;
changed = true;
}
Ok(changed)View on GitHub (pinned to a747e741ae)
Solutions
- Treat git's 'nothing to unset' exit code (5) as success so cleanup is idempotent
- Check whether the key/value actually exists with `git config --global --get-all <key>`
- Remove stale ~/.gitconfig.lock and verify the config parses
- Ensure HOME is writable in the execution environment
Example fix
// before: any nonzero exit is an error
if !status.success() {
anyhow::bail!("git config --global --unset-all {} failed", key);
}
// after: tolerate 'nothing to unset'
if !status.success() && status.code() != Some(5) {
anyhow::bail!("git config --global --unset-all {} failed", key);
} Defensive patterns
Strategy: validation
Validate before calling
fn rewrite_exists(key: &str, value: &str) -> bool {
std::process::Command::new("git")
.args(["config", "--global", "--get-all", key, value])
.output()
.map(|o| o.status.success()).unwrap_or(false)
}
// only attempt unset when the entry actually exists
if rewrite_exists(key, value) { remove_url_rewrite(key)?; } Try / catch
match remove_url_rewrite(key) {
Ok(_) => println!("rewrite removed (or already absent)"),
Err(e) if e.to_string().contains("--unset-all") => {
// git exits 5 when there is nothing to unset — treat as idempotent success
eprintln!("unset failed: {e:#}; entry may not exist");
}
Err(e) => return Err(e),
} Prevention
- Check entry existence with `git config --global --get-all` before unsetting
- Treat git's exit code 5 (nothing to unset) as success for idempotent cleanup
- Keep HOME writable and free of stale config.lock files
- Don't call remove for rewrites that were never added
When it happens
Trigger: remove_url_rewrite calls git_config_unset_all when the global config is unwritable/corrupt, HOME is misconfigured, a config.lock exists — or when no matching entry exists so git returns exit code 5 (nothing to unset).
Common situations: Trying to remove a rewrite that was never added (idempotent cleanup treated as failure); CI environments with read-only HOME; leftover config.lock; malformed gitconfig preventing parsing.
Related errors
- git config --global --unset {} failed
- git config --global {} failed
- git config --global --add {} failed
- git {} failed
- git config --global {} failed
AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01).
Data as JSON: /api/errors/4418748002c03310.
Report an issue: GitHub.