asdf-vm/asdf · error

<dynamic msg passed to printError>

Error message

<dynamic msg passed to printError>

What it means

printError in internal/cli/set writes the given message to stderr (ensuring a trailing newline) and returns it as a new error. This is the generic failure path for the `asdf set` command, so the message is dynamic — it describes whatever validation or filesystem problem occurred.

Source

Thrown at internal/cli/set/set.go:98

		err = toolversions.WriteToolVersionsToFile(path, []toolversions.ToolVersions{tv})
		if err != nil {
			err = printError(stderr, fmt.Sprintf("error writing version file: %s", err))
		}
		return err
	}

	// Write new file in current dir
	filepath := filepath.Join(currentDir, conf.DefaultToolVersionsFilename)
	return toolversions.WriteToolVersionsToFile(filepath, []toolversions.ToolVersions{tv})
}

func printError(stderr io.Writer, msg string) error {
	if !strings.HasSuffix(msg, "\n") {
		msg += "\n"
	}
	fmt.Fprint(stderr, msg)
	return errors.New(strings.TrimSuffix(msg, "\n"))
}

func findVersionFileInParentDir(conf config.Config, directory string) (string, bool) {
	directory = filepath.Dir(directory)

	for {
		path := filepath.Join(directory, conf.DefaultToolVersionsFilename)
		if _, err := os.Stat(path); err == nil {
			return path, true
		}

		if directory == "/" {
			return "", false
		}

		directory = filepath.Dir(directory)
	}
}

View on GitHub (pinned to 074a1722ca)

Solutions

  1. Read the stderr message printed by the command — it names the specific problem
  2. Verify the tool/plugin and version exist (`asdf plugin list`, `asdf list <tool>`) before running `asdf set`
  3. Check write permissions on the .tool-versions file / directory you are setting the version in

Example fix

// before
$ asdf set nodejs 99.9   # version never installed
// after
$ asdf install nodejs 20.12.0 && asdf set nodejs 20.12.0
Defensive patterns

Strategy: try-catch

Validate before calling

// Go caller of the set command path
if tool == "" || version == "" {
    return fmt.Errorf("asdf set requires <tool> <version>")
}
if _, err := os.Stat(filepath.Join(dir, ".tool-versions")); err != nil {
    // decide whether creating it is intended
}

Try / catch

if err := setCmd(args); err != nil {
    // err text is the same message written to stderr; surface it to the user
    fmt.Fprintf(os.Stderr, "asdf set failed: %v\n", err)
}

Prevention

When it happens

Trigger: Any failure inside `asdf set` handling that Main routes through printError: invalid arguments, unresolvable tool/version, inability to find or write a .tool-versions file, or permission errors when setting the version.

Common situations: Running `asdf set` in a directory where no .tool-versions exists and creation fails; specifying a tool with no plugin installed; typos in version strings; read-only or permission-restricted config files.

Related errors


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