{"record":{"id":"346f3b438bfc7ac3","repo":"asdf-vm/asdf","slug":"unable-to-clone-plugin-s","errorCode":null,"errorMessage":"unable to clone plugin: %s","messagePattern":"unable to clone plugin: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/git/git.go","lineNumber":52,"sourceCode":"\tURL       string\n}\n\n// NewRepo builds a new Repo instance\nfunc NewRepo(directory string) Repo {\n\treturn Repo{Directory: directory}\n}\n\n// Clone installs a plugin via Git\nfunc (r Repo) Clone(pluginURL, ref string) error {\n\tcmdStr := []string{\"git\", \"clone\", \"--depth\", \"1\", pluginURL, r.Directory}\n\n\tif ref != \"\" {\n\t\tcmdStr = []string{\"git\", \"clone\", \"--depth\", \"1\", pluginURL, r.Directory, \"--branch\", ref}\n\t}\n\n\t_, stderr, err := exec(cmdStr)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"unable to clone plugin: %s\", stdErrToErrMsg(stderr))\n\t}\n\n\treturn nil\n}\n\n// Head returns the current HEAD ref of the plugin's Git repository\nfunc (r Repo) Head() (string, error) {\n\terr := repositoryExists(r.Directory)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tstdout, stderr, err := exec([]string{\"git\", \"-C\", r.Directory, \"rev-parse\", \"HEAD\"})\n\tif err != nil {\n\t\treturn \"\", errors.New(stdErrToErrMsg(stderr))\n\t}\n\n\treturn strings.TrimSpace(stdout), nil","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/asdf-vm/asdf/blob/074a1722ca88d6677f228541ce06efaf4f9924d4/internal/git/git.go#L34-L70","documentation":"git.Clone runs `git clone` (optionally with --depth 1 and --branch <ref>) to fetch a plugin repository into its local directory. If the git command exits non-zero, the stderr output is surfaced as \"unable to clone plugin: <message>\".","triggerScenarios":"Plugin URL is wrong or the repo doesn't exist; no network access or a proxy blocks github.com; the requested --branch ref does not exist; target directory is not writable or already exists non-empty; git not installed or auth required for a private repo.","commonSituations":"Typos in `asdf plugin add <name> <url>`; corporate firewalls/SSL interception; cloning a private plugin repo without credentials; shallow clone of a ref that was force-removed upstream.","solutions":["Verify the plugin URL and that the repo/branch exists; re-run with the corrected URL.","Check network/proxy/SSL settings; test `git clone <url>` manually to see the raw error.","For private repos configure SSH keys or credentials before `asdf plugin add`.","Remove a stale target directory and retry: `rm -rf ~/.asdf/plugins/<name>` then re-add."],"exampleFix":"# before\nasdf plugin add nodejs https://wrong-url.example/nodejs.git\n# after\nasdf plugin add nodejs https://github.com/asdf-vm/asdf-nodejs.git","handlingStrategy":"retry","validationCode":"git ls-remote \"$PLUGIN_URL\" >/dev/null 2>&1 || { echo \"unreachable: $PLUGIN_URL\"; exit 1; }\ncommand -v git >/dev/null || { echo \"git required\"; exit 1; }","typeGuard":null,"tryCatchPattern":"for i in 1 2 3; do\n  asdf plugin add \"$NAME\" \"$URL\" && break\n  sleep $((i * 2))\ndone","preventionTips":["Verify plugin URLs before asdf plugin add","Test `git clone <url>` manually to surface raw git errors","Configure credentials/SSH keys for private plugin repos","Check proxy/SSL settings in corporate environments","Retry on transient network failures"],"tags":["git","network","plugins","clone"],"backgroundTag":"git-clone-failed","analyzedSha":"074a1722ca88d6677f228541ce06efaf4f9924d4","analyzedAt":"2026-08-30T19:56:42.972Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}