{"record":{"id":"4becad094cbddda3","repo":"asdf-vm/asdf","slug":"failed-to-run-pre-download-hook-w","errorCode":null,"errorMessage":"failed to run pre-download hook: %w","messagePattern":"failed to run pre-download hook: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/versions/versions.go","lineNumber":179,"sourceCode":"\t}\n\n\tconcurrency, _ := conf.Concurrency()\n\tenv := map[string]string{\n\t\t\"ASDF_INSTALL_TYPE\":    version.Type,\n\t\t\"ASDF_INSTALL_VERSION\": version.Value,\n\t\t\"ASDF_INSTALL_PATH\":    installDir,\n\t\t\"ASDF_DOWNLOAD_PATH\":   downloadDir,\n\t\t\"ASDF_CONCURRENCY\":     concurrency,\n\t}\n\n\terr = os.MkdirAll(downloadDir, 0o777)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"unable to create download dir: %w\", err)\n\t}\n\n\terr = hook.RunWithOutput(conf, fmt.Sprintf(\"pre_asdf_download_%s\", plugin.Name), []string{version.Value}, stdOut, stdErr)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to run pre-download hook: %w\", err)\n\t}\n\n\terr = plugin.RunCallback(\"download\", []string{}, env, stdOut, stdErr)\n\tif _, ok := err.(plugins.NoCallbackError); err != nil && !ok {\n\t\treturn fmt.Errorf(\"failed to run download callback: %w\", err)\n\t}\n\n\terr = hook.RunWithOutput(conf, fmt.Sprintf(\"pre_asdf_install_%s\", plugin.Name), []string{version.Value}, stdOut, stdErr)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to run pre-install hook: %w\", err)\n\t}\n\n\terr = os.MkdirAll(installDir, 0o777)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"unable to create install dir: %w\", err)\n\t}\n\n\terr = plugin.RunCallback(\"install\", []string{}, env, stdOut, stdErr)","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/asdf-vm/asdf/blob/074a1722ca88d6677f228541ce06efaf4f9924d4/internal/versions/versions.go#L161-L197","documentation":"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.","triggerScenarios":"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.","commonSituations":"Corporate pre-download hooks doing license/security checks that fail, hook commands missing from PATH, or hooks failing on a particular tool version.","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"],"exampleFix":"// before (in asdf config)\npre_asdf_download = /usr/local/bin/check-license $version  # exits 1\n// after\npre_asdf_download = /usr/local/bin/check-license $version || true","handlingStrategy":"try-catch","validationCode":"// test hooks beforehand:\nif err := hook.RunWithOutput(conf, \"pre_asdf_download_\"+plugin, []string{ver}, buf, buf); err != nil {\n    return fmt.Errorf(\"pre-download hook will fail: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"failed to run pre-download hook\") {\n    // inspect hook output, fix or bypass hook, retry\n}","preventionTips":["Test asdf hooks after editing asdfrc","Capture hook stdout/stderr in logs for diagnosis"],"tags":["hooks","install","asdf"],"backgroundTag":"hook-execution-failed","analyzedSha":"074a1722ca88d6677f228541ce06efaf4f9924d4","analyzedAt":"2026-08-30T19:56:42.972Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}