nikivdev/code · error
jj git fetch failed: {}
Error message
jj git fetch failed: {} What it means
Thrown in src/sync.rs when the internal `jj git fetch` invocation fails. The tool collects per-remote fetch failures and, if any remain after the fetch attempt, bails with the joined error messages. This wraps lower-level jj/git fetch errors (network auth, missing remote, refspec problems).
Source
Thrown at src/sync.rs:3517
failures.push(format!(
"origin alias {}: {}",
upstream_branch_for_fetch, err
));
} else {
fetched_any = true;
}
}
if fetched_any {
recorder.record("jj", "jj git import");
let _ = jj_run_in(repo_root, &["--quiet", "git", "import"]);
print_fetched_remote_commits(repo_root, &tracked_refs, recorder, cmd.compact);
// Re-resolve after fetch/import so we can pick up newly discovered upstream refs.
if home_branch_sync_target.is_none() {
upstream_branch_opt = resolve_upstream_branch_in(repo_root, Some(¤t_branch));
}
} else if !failures.is_empty() {
bail!("jj git fetch failed: {}", failures.join(", "));
}
}
let push_remote_url =
git_capture_in(repo_root, &["remote", "get-url", &push_remote]).unwrap_or_default();
let upstream_url =
git_capture_in(repo_root, &["remote", "get-url", "upstream"]).unwrap_or_default();
let is_read_only =
has_upstream && normalize_git_url(&push_remote_url) == normalize_git_url(&upstream_url);
let mut dest_ref: Option<String> = None;
if let Some(target) = home_branch_sync_target.as_ref() {
dest_ref = Some(format!(
"{}@{}",
target.public_default_branch, target.public_remote
));
} else if has_upstream {
if let Some(branch) = upstream_branch_opt {View on GitHub (pinned to a747e741ae)
Solutions
- Read the joined message after the colon — it names the failing remote/reason; fix that specific issue (e.g., `ssh -T git@host` to test auth).
- Verify the remote exists: `git remote -v` / `jj git remote list`, and re-add if missing (`jj git remote add origin <url>`).
- Retry when network/VPN is up; fetch is safe to re-run.
- Refresh credentials: start ssh-agent with the key, or update HTTPS token in your credential helper.
Example fix
// before jj git fetch origin // error: authentication failed for 'https://gitlab.com/team/repo.git' // after (refresh credentials then re-run sync) git credential reject <<EOF protocol=https host=gitlab.com EOF f sync
Defensive patterns
Strategy: retry
Validate before calling
git ls-remote origin HEAD >/dev/null 2>&1 || { echo "origin unreachable or auth failed"; exit 1; } Try / catch
match sync::run(&repo_root, &cmd) {
Err(e) if e.to_string().starts_with("jj git fetch failed:") => {
eprintln!("Fetch failed: {} — check auth/network, then retry", e);
// retry with backoff
}
other => other,
} Prevention
- Keep your SSH key loaded in ssh-agent (ssh-add) before long work sessions.
- Periodically refresh HTTPS tokens / credential-helper entries before they expire.
- Verify remotes exist with `jj git remote list` / `git remote -v` after team repo migrations.
- Check network/VPN connectivity before running sync in CI or scripts.
When it happens
Trigger: Executing the sync command when `jj git fetch` returns failures for one or more remotes — the `else if !failures.is_empty()` branch. Any non-empty `failures` list (e.g., SSH auth rejected, remote URL unreachable, unknown remote name) triggers it.
Common situations: SSH key not loaded in agent or wrong passphrase; remote renamed/removed; no network/VPN; jj repo not colocated with git so the git remote isn't registered with jj; credentials expired.
Related errors
- git push failed
- git fetch {} --prune failed: {}
- device auth start failed: HTTP {}
- device auth poll failed: HTTP {}
- git pull failed
AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01).
Data as JSON: /api/errors/c6e182880cd1a52a.
Report an issue: GitHub.