jdx/mise · error
--postinstall requires a TOML config file
Error message
--postinstall requires a TOML config file
What it means
`mise use --postinstall` writes a tool target with a postinstall hook into the active config file. mise only supports persisting postinstall directives in TOML-based config files (mise.toml / .mise.toml etc.), so it throws this bail when any --postinstall target is requested while the resolved config source is not a MiseToml file (e.g. .tool-versions, or no config file at all).
Solutions
- Convert the project config to mise.toml (e.g. `mise use` without --postinstall first creates/uses mise.toml, or rename/migrate .tool-versions to mise.toml) and re-run with --postinstall.
- Put the tool plus [tools] postinstall hook directly in mise.toml instead of using the CLI flag.
- Drop --postinstall and run the install hook manually via `mise install` scripts or a task.
Example fix
// before (fails: .tool-versions present) mise use --postinstall "npm run prepare" node@22 // after cat > mise.toml <<'EOF' [tools] node = "22" EOF mise use --postinstall "npm run prepare" node@22
Defensive patterns
Strategy: validation
Validate before calling
if mise_use_args.contains('--postinstall') && !config_path.ends_with(".toml") {
eprintln!('--postinstall needs a mise.toml config; migrate .tool-versions first');
} Try / catch
match mise_use(&args) {
Err(e) if e.to_string().contains("requires a TOML config file") => migrate_to_mise_toml()? ,
r => r?,
} Prevention
- Keep projects on mise.toml rather than .tool-versions before using advanced flags
- Check `mise config ls` to confirm the resolved config is TOML
- Avoid --postinstall in scripts targeting legacy configs
When it happens
Trigger: Running `mise use --postinstall <cmd> tool@version` (ToolArg.postinstall set) when `get_config_file().source()` is not ToolSource::MiseToml — e.g. the project uses .tool-versions, only a global non-TOML source resolves, or no config file exists in the current directory tree.
Common situations: Projects still using asdf-style .tool-versions files; users in a directory with no mise config so `mise use` would fall back to creating a non-TOML config; scripts that pass --postinstall to a `mise use` invocation pointed at legacy configs.
Understand the failure class
Background: "Unknown argument", "Invalid value", and "must be one of": invalid CLI argument errors explained — this error's family across 35 libraries.
Related errors
- collection updates require scalar or array values
- config set requires a TOML config file, but
- scalar values were converted to arrays
- --tool-option requires a TOML config file
- backend must be a string or table
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/19777e65ff4bb15b.
Report an issue: GitHub.
Appendix: source
Thrown at src/cli/use.rs:267
.iter()
.map(|target| target.tool.clone())
.collect::<Vec<_>>();
env::TOOL_ARGS.write().unwrap().clone_from(&tool_args);
let mut config = Config::get().await?;
let scope = if self.global {
ConfigScope::GlobalOnly
} else {
ConfigScope::All
};
let mut ts = ToolsetBuilder::new()
.with_scope(scope)
.build(&config)
.await?;
let mut cf = self.get_config_file().await?;
if self.tools.iter().any(|target| target.postinstall.is_some())
&& !matches!(cf.source(), ToolSource::MiseToml(_))
{
bail!("--postinstall requires a TOML config file");
}
if self
.tools
.iter()
.any(|target| !target.tool_option.is_empty())
&& !matches!(cf.source(), ToolSource::MiseToml(_))
{
bail!("--tool-option requires a TOML config file");
}
let pin = self.pin || !self.fuzzy && (Settings::get().pin || Settings::get().asdf_compat);
let mut resolve_options = ResolveOptions {
latest_versions: false,
use_locked_version: true,
resolve_rolling_channels: false,
prefer_exact_version: pin,
before_date: self.get_before_date()?,
before_date_from_default: false,
filter_installed_versions_by_release_date: false,View on GitHub (pinned to 533346cc37)