asdf-vm/asdf · error

failed to run install callback: %w

Error message

failed to run install callback: %w

What it means

InstallOneVersion runs the plugin's 'install' callback inside the install directory. Unlike the download callback, install is mandatory here: any error returned by RunCallback (including NoCallbackError) is wrapped as 'failed to run install callback'. A non-zero exit from the plugin's install script produces this error.

Source

Thrown at internal/installtest/installtest.go:61

	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))
}

// DownloadPath returns the download path for a particular plugin and version
func DownloadPath(conf config.Config, plugin plugins.Plugin, version string) string {
	return filepath.Join(conf.DataDir, dataDirDownloads, plugin.Name, formatVersionStringForFS(version))
}

func pluginInstallPath(conf config.Config, plugin plugins.Plugin) string {
	return filepath.Join(conf.DataDir, dataDirInstalls, plugin.Name)
}

View on GitHub (pinned to 074a1722ca)

Solutions

  1. Inspect the wrapped error plus the stdOut/stdErr captured during the run for the callback's real failure output.
  2. Run the plugin's install callback manually in the install dir to see the underlying failure.
  3. Install the missing system dependency or toolchain the callback needs.
  4. Fix or report the plugin script bug (e.g. add your platform to its OS/arch switch).

Example fix

// plugin bin/install missing build tool
# before
cargo build --release
# after
type cargo >/dev/null 2>&1 || { echo "cargo is required" >&2; exit 1; }
cargo build --release
Defensive patterns

Strategy: try-catch

Validate before calling

if fi, err := os.Stat(filepath.Join(pluginDir, "bin", "install")); err != nil || fi.IsDir() {
    return fmt.Errorf("plugin %s has no install callback", name)
}
if fi.Mode()&0o111 == 0 {
    return fmt.Errorf("install callback not executable")
}

Try / catch

err := installtest.InstallOneVersion(conf, plugin, version)
if err != nil {
    if strings.Contains(err.Error(), "failed to run install callback") {
        // print captured stdOut/stdErr from the callback for the real cause
        log.Fatalf("install callback failed: %v", err)
    }
}

Prevention

When it happens

Trigger: Calling InstallOneVersion when: the plugin has no install callback (NoCallbackError is NOT tolerated); the install callback exits non-zero (build failure, missing system dependency, unsupported platform/OS branch in the script); the callback script cannot be executed.

Common situations: Installing a tool version that requires a build toolchain (make, cargo, python) absent from the machine; plugin script lacks a case branch for your OS/arch; downloading during install blocked by a proxy or firewall; corrupted or incomplete download from the previous step.

Related errors


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