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

  1. Re-clone the plugin: `asdf plugin remove <plugin>` then `asdf plugin add <plugin> <url>`.
  2. Run `git -C ~/.asdf/plugins/<plugin> fsck` / `git status` to diagnose corruption.
  3. Retry `asdf plugin update <plugin>` after fixing disk/permission problems.
  4. 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

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


AI-assisted analysis of asdf-vm/asdf@074a1722ca (2026-08-30). Data as JSON: /api/errors/3414c11a8273029e. Report an issue: GitHub.