jdx/mise · error
global configuration branch differs from the transferred bra
Error message
global configuration branch differs from the transferred branch
What it means
When `--update` is requested and the destination is already a Git checkout, install_at compares the destination's current branch (`git symbolic-ref --short HEAD`) with the branch of the transferred bundle. If they differ, the fast-forward-only update cannot proceed, because the tool never merges across branches. It aborts to avoid switching or merging the user's checked-out branch implicitly.
Source
Thrown at src/system/remote_repository.rs:261
git(
&checkout,
&["-c", "core.hooksPath=/dev/null", "checkout", &branch],
)?;
if destination.join(".git").exists() {
if git(destination, &["remote", "get-url", "origin"])? != origin {
bail!("global configuration origin does not match");
}
if !git(
destination,
&["status", "--porcelain", "--untracked-files=no"],
)?
.is_empty()
{
bail!("global configuration has uncommitted changes");
}
if update {
if git(destination, &["symbolic-ref", "--short", "HEAD"])? != branch {
bail!("global configuration branch differs from the transferred branch");
}
if dry_run {
// the bundle holds the history from the checkout's commit on,
// so the fast-forward is checked there without fetching into
// the destination
let head = git(destination, &["rev-parse", "HEAD"])?;
if head == revision {
miseprintln!(
"Would keep {shown} at {revision}, already the transferred revision"
);
} else if git(&checkout, &["merge-base", "--is-ancestor", &head, revision]).is_ok()
{
miseprintln!("Would fast-forward {shown} from {head} to {revision}");
} else {
bail!(
"global configuration at {shown} cannot be fast-forwarded to the transferred revision"
);
}View on GitHub (pinned to afd2eddd3a)
Solutions
- Switch the destination to the transferred branch: `git -C <destination> checkout <transferred-branch>`.
- Rename the destination branch to match: `git -C <destination> branch -m <old> <transferred-branch>`.
- Align the source repository so its checked-out branch matches what the destination expects (e.g. keep `main` everywhere).
- If the old branch is obsolete, fast-forward it to the transferred branch first, then switch.
Example fix
// before: destination on 'master', transfer branch is 'main' git -C ~/.config/mise branch -m master main // after: branch matches the transferred branch; rerun with --update
Defensive patterns
Strategy: validation
Validate before calling
const branch = execFileSync('git', ['-C', dest, 'symbolic-ref', '--short', 'HEAD']).toString().trim();
const expected = 'main'; // branch of the transferred bundle
if (branch !== expected) throw new Error(`destination on ${branch}, transfer expects ${expected}`); Prevention
- Standardize one default branch name across all clones of the config repo.
- Avoid manually checking out feature branches in the destination checkout.
- After a default-branch rename upstream, run `git branch -m` in existing clones.
When it happens
Trigger: Running an update where the destination checkout is on branch X (e.g. `main`) while the transferred repository's HEAD branch is Y (e.g. `master` or a renamed branch).
Common situations: Source repo renamed its default branch (master→main) but destination still sits on the old name; user manually checked out a feature branch in the config repo; fresh clones elsewhere default to a different branch.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- no setup repository is connected; `mise bootstrap dotfiles o
- global configuration origin does not match
- global configuration has uncommitted changes
- remote task path is not a regular file or directory: {}
- cannot encode #{value.class} as JSON
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/89bdc6c5b708254b.
Report an issue: GitHub.