jdx/mise · error
[daemons. ] requires preset when specifying version or…
Error message
[daemons.{name}] requires preset when specifying version or options What it means
A `[daemons.<name>]` entry without a `preset` must be fully self-contained: it may not specify `version` or `options`, because those only make sense as inputs to a preset's expansion. If version or options appear without a preset, mise bails with this message during config load.
Solutions
- Add the intended `preset = "..."` key alongside version/options.
- Or remove the `version` and `options` keys and provide `run = "..."` directly.
- Check other declarations of the same daemon (merging layers) — one layer may set preset while yours sets only version/options.
Example fix
# before [daemons.postgres] version = "16" # after (preset form) [daemons.postgres] preset = "postgres" version = "16" # or direct form [daemons.postgres] run = "postgres -D data"
Defensive patterns
Strategy: validation
Validate before calling
# shell: flag daemons with version/options but no preset
awk '/^\[daemons\./{blk=$0} /version|options/{if (blk !~ /preset/) print blk}' mise.toml Prevention
- Remember `version` and `options` are preset-only fields; standalone daemons use `run` only.
- When converting a preset daemon to a direct command, delete both `preset` and `version`/`options`.
- Review each daemon block for the complete required trio: preset (with version) or run.
When it happens
Trigger: Declaring `[daemons.foo]` with a `version` key and/or an `options` table but no `preset` key; the declaration is validated in `load` when the config is parsed (e.g. by task execution or env expansion).
Common situations: Users assuming `version`/`options` are generic daemon fields; converting a preset-based entry by deleting the `preset` line but leaving `version`; TOML examples copied from preset-based docs.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- [daemons. ] requires run or preset
- command wrapper for must have a non-blank command
- daemon port must be an integer from 1 to 65535
- expected a string, array of strings, or table with `run`
- invalid daemon name ; use letters, numbers, '.', '_' or
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/6674717115f69cbb.
Report an issue: GitHub.
Appendix: source
Thrown at src/daemons/mod.rs:98
.all(|c| c.is_ascii_alphanumeric() || matches!(c, '_' | '-' | '.'))
{
bail!("invalid daemon name {name:?}; use letters, numbers, '.', '_' or '-'");
}
let (preset, version, mut table) = match declaration {
Declaration::Preset(version) => (Some(name.clone()), Some(version), toml::Table::new()),
Declaration::Definition(mut table) => {
let preset = take_string(&mut table, "preset")?;
let version = take_string(&mut table, "version")?;
(preset, version, table)
}
};
let daemon = if let Some(preset) = preset {
let version = version
.ok_or_else(|| eyre::eyre!("[daemons.{name}] requires version with preset"))?;
presets::expand(&name, &preset, &version, table, &source, &root)?
} else {
if version.is_some() || table.contains_key("options") {
bail!("[daemons.{name}] requires preset when specifying version or options");
}
if table.get("run").and_then(toml::Value::as_str).is_none() {
bail!("[daemons.{name}] requires run or preset");
}
if let Some(port) = table.get("port").and_then(toml::Value::as_integer) {
if !(1..=65535).contains(&port) {
bail!("daemon port must be an integer from 1 to 65535");
}
table.insert(
"port".into(),
toml::Value::Table(toml::Table::from_iter([
(
"expect".into(),
toml::Value::Array(vec![toml::Value::Integer(port)]),
),
("bump".into(), toml::Value::Boolean(false)),
])),
);View on GitHub (pinned to 533346cc37)