asdf-vm/asdf · error
failed to run pre-download hook: %w
Error message
failed to run pre-download hook: %w
What it means
Before downloading, InstallOneVersion runs the pre_asdf_download hook via hook.RunWithOutput, which executes user-configured hook commands (from asdf config, e.g. pre_asdf_download_nodejs) and surfaces their failure. A non-zero hook exit is wrapped as 'failed to run pre-download hook', aborting the install before the plugin's download callback runs.
Source
Thrown at internal/versions/versions.go:179
}
concurrency, _ := conf.Concurrency()
env := map[string]string{
"ASDF_INSTALL_TYPE": version.Type,
"ASDF_INSTALL_VERSION": version.Value,
"ASDF_INSTALL_PATH": installDir,
"ASDF_DOWNLOAD_PATH": downloadDir,
"ASDF_CONCURRENCY": concurrency,
}
err = os.MkdirAll(downloadDir, 0o777)
if err != nil {
return fmt.Errorf("unable to create download dir: %w", err)
}
err = hook.RunWithOutput(conf, fmt.Sprintf("pre_asdf_download_%s", plugin.Name), []string{version.Value}, stdOut, stdErr)
if err != nil {
return fmt.Errorf("failed to run pre-download hook: %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 = hook.RunWithOutput(conf, fmt.Sprintf("pre_asdf_install_%s", plugin.Name), []string{version.Value}, stdOut, stdErr)
if err != nil {
return fmt.Errorf("failed to run pre-install hook: %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)View on GitHub (pinned to 074a1722ca)
Solutions
- Look at the hook's own output on stdOut/stdErr for the real failure
- Inspect the pre_asdf_download hook definition in asdf config and fix or remove it
- Ensure the hook command exists in PATH and is executable
- Retry the install after the hook's blocking condition (e.g. approval, network policy) is resolved
Example fix
// before (in asdf config) pre_asdf_download = /usr/local/bin/check-license $version # exits 1 // after pre_asdf_download = /usr/local/bin/check-license $version || true
Defensive patterns
Strategy: try-catch
Validate before calling
// test hooks beforehand:
if err := hook.RunWithOutput(conf, "pre_asdf_download_"+plugin, []string{ver}, buf, buf); err != nil {
return fmt.Errorf("pre-download hook will fail: %w", err)
} Try / catch
if err != nil && strings.Contains(err.Error(), "failed to run pre-download hook") {
// inspect hook output, fix or bypass hook, retry
} Prevention
- Test asdf hooks after editing asdfrc
- Capture hook stdout/stderr in logs for diagnosis
When it happens
Trigger: hook.RunWithOutput(conf, "pre_asdf_download_<plugin>", [version], ...) returns an error — a configured pre_asdf_download or pre_asdf_download_<plugin> hook exits non-zero or cannot be executed.
Common situations: Corporate pre-download hooks doing license/security checks that fail, hook commands missing from PATH, or hooks failing on a particular tool version.
Related errors
- failed to run pre-install hook: %w
- command removed
- unable to create download dir: %w
- failed to run download callback: %w
- unable to create install dir: %w
AI-assisted analysis of asdf-vm/asdf@074a1722ca (2026-08-30).
Data as JSON: /api/errors/4becad094cbddda3.
Report an issue: GitHub.