asdf-vm/asdf · error
failed to run download callback: %w
Error message
failed to run download callback: %w
What it means
asdf's InstallOneVersion runs the plugin's optional 'download' callback in a temporary download directory. The download callback exists but returned a non-zero exit or the spawned command failed, and the failure was NOT a plugins.NoCallbackError (which is intentionally tolerated since the callback is optional). asdf wraps the underlying error so the plugin author's failure surfaces during installation testing.
Source
Thrown at internal/installtest/installtest.go:51
downloadDir := DownloadPath(conf, plugin, version)
installDir := InstallPath(conf, plugin, version)
env := map[string]string{
"ASDF_INSTALL_TYPE": versionType,
"ASDF_INSTALL_VERSION": version,
"ASDF_INSTALL_PATH": installDir,
"ASDF_DOWNLOAD_PATH": downloadDir,
"ASDF_CONCURRENCY": "1",
}
err = os.MkdirAll(downloadDir, 0o777)
if err != nil {
return fmt.Errorf("unable to create download dir: %w", err)
}
err = plugin.RunCallback("download", []string{}, env, &stdOut, &stdErr)
if _, ok := err.(plugins.NoCallbackError); err != nil && !ok {
return fmt.Errorf("failed to run download callback: %w", err)
}
err = os.MkdirAll(installDir, 0o777)
if err != nil {
return fmt.Errorf("unable to create install dir: %w", err)
}
err = plugin.RunCallback("install", []string{}, env, &stdOut, &stdErr)
if err != nil {
return fmt.Errorf("failed to run install callback: %w", err)
}
return nil
}
// InstallPath returns the path to a tool installation
func InstallPath(conf config.Config, plugin plugins.Plugin, version string) string {
return filepath.Join(pluginInstallPath(conf, plugin), formatVersionStringForFS(version))View on GitHub (pinned to 074a1722ca)
Solutions
- Inspect the wrapped error and the plugin's download callback script; run it manually to reproduce the failure.
- Fix the plugin's download callback (missing dependency, bad URL, wrong shebang, non-zero exit).
- Ensure required tools/env vars the callback relies on are available in the install environment.
- If the callback should be optional/absent, remove it entirely so NoCallbackError applies and is skipped.
Example fix
// plugin lib/utils.bash download callback failing # before curl -sSL "$release_url" | tar xz # after (check failure and give a clear message) curl --fail -sSL "$release_url" -o /tmp/pkg.tar.gz || exit 1 mkdir -p "$ASDF_DOWNLOAD_PATH" tar xzf /tmp/pkg.tar.gz -C "$ASDF_DOWNLOAD_PATH" --strip-components=1
Defensive patterns
Strategy: type-guard
Validate before calling
if _, err := os.Stat(filepath.Join(pluginDir, "lib", "utils.bash")); err == nil {
// plugin defines callbacks; ensure deps like curl/git exist
if _, err := exec.LookPath("git"); err != nil {
return fmt.Errorf("download callback needs git: %w", err)
}
} Type guard
var nce plugins.NoCallbackError
if errors.As(err, &nce) {
// optional callback absent — tolerate
} else if err != nil {
return fmt.Errorf("download failed: %w", err)
} Try / catch
if err := installtest.InstallOneVersion(conf, plugin, version); err != nil {
var nce plugins.NoCallbackError
if errors.As(err, &nce) {
// tolerated: callback missing
} else {
log.Printf("download callback failed: %v", err)
}
} Prevention
- Run the plugin's download callback manually in a scratch dir before installing.
- Ensure curl/git and other callback dependencies are installed in CI images.
- Keep callbacks' error output visible (capture stdOut/stdErr) for diagnosis.
- Pin plugin versions tested with your asdf version.
When it happens
Trigger: Calling InstallOneVersion (used by `asdf install` and plugin test tooling) when: the plugin defines a download callback that exits non-zero; the callback script itself crashes (bad interpreter, syntax error); or RunCallback fails for a non-NoCallbackError reason such as the callback file not being executable or the fork/exec failing.
Common situations: Plugin authors shipping a broken download script; callback referencing missing environment variables or tools (curl, git) not present on the machine; restrictive permissions making the callback non-executable; users installing a plugin whose download URL is dead or behind an auth wall.
Related errors
- failed to run install callback: %w
- failed to run download callback: %w
- unable to create download dir: %w
- unable to create install dir: %w
- unable to list plugins: %w
AI-assisted analysis of asdf-vm/asdf@074a1722ca (2026-08-30).
Data as JSON: /api/errors/701c12640be16f9b.
Report an issue: GitHub.