asdf-vm/asdf · error
unable to update plugin index: %w
Error message
unable to update plugin index: %w
What it means
doUpdate refreshes an existing plugin index repository with p.repo.Update("") (fetch to latest commit). If the git update fails, the error is wrapped as 'unable to update plugin index'. This path only runs when the index already exists but is older than the staleness threshold.
Source
Thrown at internal/pluginindex/pluginindex.go:109
return p.doUpdate()
}
// Convert minutes to nanoseconds
updateDurationNs := int64(p.updateDurationMinutes) * (6e10)
if updated > updateDurationNs && !p.disableUpdate {
return p.doUpdate()
}
return false, nil
}
func (p PluginIndex) doUpdate() (bool, error) {
// pass in empty string as we want the repo to figure out what the latest
// commit is
_, _, _, err := p.repo.Update("")
if err != nil {
return false, fmt.Errorf("unable to update plugin index: %w", err)
}
// Touch update file
return touchFS(p.directory)
}
// GetPluginSourceURL looks up a plugin by name and returns the repository URL
// for easy install by the user.
func (p PluginIndex) GetPluginSourceURL(name string) (string, error) {
_, err := p.Refresh()
if err != nil {
return "", err
}
url, err := readPlugin(p.directory, name)
if err != nil {
return "", err
}View on GitHub (pinned to 074a1722ca)
Solutions
- Check network access to the index remote and retry — updates are transient failures.
- Delete the index directory (default ~/.asdf/repository or repo/ under the index dir) and let Refresh re-clone it.
- Fix the local clone manually (git -C <dir> fetch && git reset --hard origin).
- Verify git/proxy configuration if behind a firewall.
Example fix
// before: corrupt/stale index repo
// after: re-clone from scratch
rm -rf "${ASDF_DATA_DIR:-$HOME/.asdf}/repository"
asdf plugin list all # triggers fresh clone Defensive patterns
Strategy: fallback
Validate before calling
if fi, err := os.Stat(filepath.Join(indexDir, ".git")); err != nil || !fi.IsDir() {
// repo missing/corrupt — remove so Refresh re-clones
os.RemoveAll(indexDir)
} Try / catch
ok, err := idx.Refresh()
if err != nil && strings.Contains(err.Error(), "unable to update plugin index") {
os.RemoveAll(indexDir) // nuke broken clone
ok, err = idx.Refresh() // fresh clone fallback
} Prevention
- On repeated update failures, delete the index repo dir to force a clean re-clone.
- Check GitHub status / rate limits before assuming local breakage.
- Avoid killing asdf mid-update; interruptions can corrupt the clone.
- Retry transient network failures before manual intervention.
When it happens
Trigger: Refresh (via Get/GetPluginSourceURL) when the index repo exists and the update-timestamp is stale, and: the network is down; the remote rejected the fetch (auth, rate limit); the local clone has diverged or is corrupt; git is unavailable.
Common situations: Intermittent network drops; GitHub outages or rate limiting; local index repo left in a dirty/broken state by a killed process; VPN disconnected.
Related errors
- unable to initialize index: %w
- error fetching plugin URL: %s
- unable to clone plugin: %s
- unable to resolve plugin new Git HEAD: %w
- unable to create file plugin index touch file: %w
AI-assisted analysis of asdf-vm/asdf@074a1722ca (2026-08-30).
Data as JSON: /api/errors/b30bb822f2cf983c.
Report an issue: GitHub.