{"record":{"id":"c08938893241c0fa","repo":"asdf-vm/asdf","slug":"unable-to-create-download-dir-w-c08938","errorCode":null,"errorMessage":"unable to create download dir: %w","messagePattern":"unable to create download dir: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/versions/versions.go","lineNumber":174,"sourceCode":"\tdownloadDir := installs.DownloadPath(conf, plugin, version)\n\tinstallDir := installs.InstallPath(conf, plugin, version)\n\n\tif installs.IsInstalled(conf, plugin, version) {\n\t\treturn VersionAlreadyInstalledError{version: version, toolName: plugin.Name}\n\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)","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/asdf-vm/asdf/blob/074a1722ca88d6677f228541ce06efaf4f9924d4/internal/versions/versions.go#L156-L192","documentation":"InstallOneVersion creates a per-install download directory (conf.DataDir/downloads/<plugin>/<version>) and exports it as ASDF_DOWNLOAD_PATH before running download hooks/callbacks. If os.MkdirAll fails — permissions, disk full, path is a file — installation aborts with this wrapped error before anything is downloaded.","triggerScenarios":"os.MkdirAll(downloadDir, 0o777) returns an error: parent dirs unwritable, ASDF_DATA_DIR on a read-only mount, disk full, or a non-directory already exists at the download path.","commonSituations":"Read-only or full filesystem, running asdf as a different user than the data dir owner, ASDF_DATA_DIR pointing at a restricted path, leftover file where the downloads dir should be.","solutions":["Check disk space (df -h) and free space if full","Fix ownership/permissions on ASDF_DATA_DIR and its downloads/ tree","Ensure ASDF_DATA_DIR is on a writable mount","Remove any non-directory file occupying the download path"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if err := os.MkdirAll(downloadDir, 0o777); err != nil {\n    return fmt.Errorf(\"download dir not writable: %w\", err)\n}\nif free, err := diskFree(dataDir); err == nil && free < minNeeded {\n    return fmt.Errorf(\"insufficient disk space\")\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"unable to create download dir\") {\n    // check disk space / permissions, then retry install\n}","preventionTips":["Monitor disk space on the ASDF_DATA_DIR volume","Keep ASDF_DATA_DIR owned by the running user","Don't place files where asdf expects download directories"],"tags":["filesystem","permissions","install"],"backgroundTag":"mkdir-failed","analyzedSha":"074a1722ca88d6677f228541ce06efaf4f9924d4","analyzedAt":"2026-08-30T19:56:42.972Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}