asdf-vm/asdf · error
unable to resolve plugin new Git HEAD: %w
Error message
unable to resolve plugin new Git HEAD: %w
What it means
After fetching in git.Update, the code resolves the repository's new HEAD via r.Head() to report the updated ref. If resolving that HEAD fails, Update returns "unable to resolve plugin new Git HEAD" wrapping the underlying git error, aborting the version reporting.
Source
Thrown at internal/git/git.go:132
commonOpts := []string{"git", "-C", r.Directory}
refSpec := fmt.Sprintf("+%s:%s", shortRef, shortRef)
cmdStr := append(commonOpts, []string{"fetch", "--prune", "--update-head-ok", remoteName, refSpec}...)
_, stderr, err := exec(cmdStr)
if err != nil {
return "", "", "", errors.New(stdErrToErrMsg(stderr))
}
cmdStr = append(commonOpts, []string{"-c", "advice.detachedHead=false", "checkout", "--force", shortRef}...)
_, stderr, err = exec(cmdStr)
if err != nil {
return "", "", "", errors.New(stdErrToErrMsg(stderr))
}
newHash, err := r.Head()
if err != nil {
return ref, oldHash, newHash, fmt.Errorf("unable to resolve plugin new Git HEAD: %w", err)
}
return ref, oldHash, newHash, nil
}
func (r Repo) defaultRemote() (string, error) {
stdout, _, err := exec([]string{"git", "-C", r.Directory, "remote"})
if err != nil {
return "", err
}
return strings.SplitN(stdout, "\n", 2)[0], nil
}
func (r Repo) remoteDefaultBranch() (string, error) {
remote, err := r.defaultRemote()
if err != nil {
return "", err
}View on GitHub (pinned to 074a1722ca)
Solutions
- Re-clone the plugin: `asdf plugin remove <plugin>` then `asdf plugin add <plugin> <url>`.
- Run `git -C ~/.asdf/plugins/<plugin> fsck` / `git status` to diagnose corruption.
- Retry `asdf plugin update <plugin>` after fixing disk/permission problems.
- Check the remote branch still exists; if force-pushed, reset the local repo or re-add.
Example fix
# before asdf plugin update nodejs # corrupt repo # after asdf plugin remove nodejs asdf plugin add nodejs https://github.com/asdf-vm/asdf-nodejs.git
Defensive patterns
Strategy: fallback
Validate before calling
git -C ~/.asdf/plugins/"$PLUGIN" status --porcelain >/dev/null 2>&1 || { echo "repo corrupt, re-add plugin"; exit 1; } Try / catch
if ! asdf plugin update "$PLUGIN"; then asdf plugin remove "$PLUGIN" && asdf plugin add "$PLUGIN" "$URL" fi
Prevention
- Avoid interrupting asdf plugin update mid-run
- Re-add plugins whose upstream force-pushed branches
- Monitor disk space to prevent .git corruption
- Run `git fsck` on plugin repos when updates misbehave
When it happens
Trigger: `asdf update` or `asdf plugin update <plugin>` when the fetch succeeded but `git rev-parse HEAD` fails — e.g. repo has no commits on the checked-out branch, corrupted .git directory, or the checked-out ref points to nothing after a failed fetch.
Common situations: Interrupted updates leaving a corrupt plugin repo; upstream force-push removing the tracked ref; disk-full or permission issues corrupting .git.
Related errors
- unable to clone plugin: %s
- no plugin name specified
- no executable for tool version
- No compatible versions available (%s %s)
- unable to create download dir: %w
AI-assisted analysis of asdf-vm/asdf@074a1722ca (2026-08-30).
Data as JSON: /api/errors/3414c11a8273029e.
Report an issue: GitHub.