{"record":{"id":"e7f5862c1ceb7a81","repo":"asdf-vm/asdf","slug":"no-such-plugin-s","errorCode":null,"errorMessage":"no such plugin: %s","messagePattern":"no such plugin: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/plugins/plugins.go","lineNumber":270,"sourceCode":"\n\tif name != \"\" {\n\t\tcommandName = fmt.Sprintf(\"command-%s\", name)\n\t}\n\n\tpath := filepath.Join(p.Dir, \"lib\", \"commands\", commandName)\n\t_, err := os.Stat(path)\n\tif errors.Is(err, os.ErrNotExist) {\n\t\treturn \"\", NoCommandError{command: name, plugin: p.Name}\n\t}\n\n\treturn path, nil\n}\n\n// Update a plugin to a specific ref, or if no ref provided update to latest\nfunc (p Plugin) Update(conf config.Config, ref string, out, errout io.Writer) (string, error) {\n\terr := p.Exists()\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"no such plugin: %s\", p.Name)\n\t}\n\n\trepo := git.NewRepo(p.Dir)\n\n\thook.Run(conf, \"pre_asdf_plugin_update\", []string{p.Name})\n\thook.Run(conf, fmt.Sprintf(\"pre_asdf_plugin_update_%s\", p.Name), []string{p.Name})\n\n\tnewRef, oldSHA, newSHA, err := repo.Update(ref)\n\tif err != nil {\n\t\treturn newRef, err\n\t}\n\n\tenv := map[string]string{\n\t\t\"ASDF_DATA_DIR\":        conf.DataDir,\n\t\t\"ASDF_PLUGIN_PATH\":     p.Dir,\n\t\t\"ASDF_PLUGIN_PREV_REF\": oldSHA,\n\t\t\"ASDF_PLUGIN_POST_REF\": newSHA,\n\t}","sourceCodeStart":252,"sourceCodeEnd":288,"githubUrl":"https://github.com/asdf-vm/asdf/blob/074a1722ca88d6677f228541ce06efaf4f9924d4/internal/plugins/plugins.go#L252-L288","documentation":"Plugin.Update calls p.Exists() first; if the plugin's directory does not exist in the data dir, it returns 'no such plugin: %s'. Updating requires the plugin to already be installed — this error signals you tried to update a plugin asdf does not know about.","triggerScenarios":"Calling Update (or `asdf plugin update <name>`) when: the plugin name is misspelled; the plugin was never added (`asdf plugin add` not run); the plugin was removed earlier; the ASDF_DATA_DIR differs from the one used to add the plugin, so the directory lookup misses.","commonSituations":"Typo on the CLI; scripts assuming a plugin exists; switching ASDF_DATA_DIR or running as a different user whose home differs; plugin dir removed manually while asdf's metadata still referenced it elsewhere.","solutions":["List installed plugins (`asdf plugin list`) and fix the name.","Add the plugin first: asdf plugin add <name> [<git-url>].","Verify ASDF_DATA_DIR/home matches the environment where the plugin was added.","Re-add the plugin if its directory was deleted manually."],"exampleFix":"// before\nasdf plugin update nodjs   # typo\n# Error: no such plugin: nodjs\n// after\nasdf plugin list\nasdf plugin update nodejs","handlingStrategy":"validation","validationCode":"exists, err := plugins.PluginExists(conf.DataDir, pluginName)\nif err != nil || !exists {\n    // add it first instead of updating\n    return plugins.Add(conf, pluginName, repoURL)\n}","typeGuard":null,"tryCatchPattern":"ref, err := plugin.Update(conf, \"\", out, errout)\nif err != nil && strings.HasPrefix(err.Error(), \"no such plugin\") {\n    log.Printf(\"%s not installed; run: asdf plugin add %s\", pluginName, pluginName)\n}","preventionTips":["Run `asdf plugin list` to confirm the exact plugin name before updating.","Ensure ASDF_DATA_DIR is consistent across your shells and scripts.","Add plugins before scripting updates against them.","Re-add plugins whose directories were removed manually."],"tags":["plugin","lookup","update"],"backgroundTag":"plugin-not-installed","analyzedSha":"074a1722ca88d6677f228541ce06efaf4f9924d4","analyzedAt":"2026-08-30T19:56:42.972Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}