{"record":{"id":"6674717115f69cbb","repo":"jdx/mise","slug":"daemons-name-requires-preset-when-specifying-version-or","errorCode":null,"errorMessage":"[daemons.{name}] requires preset when specifying version or options","messagePattern":"\\[daemons\\.(.+?)\\] requires preset when specifying version or options","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/daemons/mod.rs","lineNumber":98,"sourceCode":"                .all(|c| c.is_ascii_alphanumeric() || matches!(c, '_' | '-' | '.'))\n        {\n            bail!(\"invalid daemon name {name:?}; use letters, numbers, '.', '_' or '-'\");\n        }\n        let (preset, version, mut table) = match declaration {\n            Declaration::Preset(version) => (Some(name.clone()), Some(version), toml::Table::new()),\n            Declaration::Definition(mut table) => {\n                let preset = take_string(&mut table, \"preset\")?;\n                let version = take_string(&mut table, \"version\")?;\n                (preset, version, table)\n            }\n        };\n        let daemon = if let Some(preset) = preset {\n            let version = version\n                .ok_or_else(|| eyre::eyre!(\"[daemons.{name}] requires version with preset\"))?;\n            presets::expand(&name, &preset, &version, table, &source, &root)?\n        } else {\n            if version.is_some() || table.contains_key(\"options\") {\n                bail!(\"[daemons.{name}] requires preset when specifying version or options\");\n            }\n            if table.get(\"run\").and_then(toml::Value::as_str).is_none() {\n                bail!(\"[daemons.{name}] requires run or preset\");\n            }\n            if let Some(port) = table.get(\"port\").and_then(toml::Value::as_integer) {\n                if !(1..=65535).contains(&port) {\n                    bail!(\"daemon port must be an integer from 1 to 65535\");\n                }\n                table.insert(\n                    \"port\".into(),\n                    toml::Value::Table(toml::Table::from_iter([\n                        (\n                            \"expect\".into(),\n                            toml::Value::Array(vec![toml::Value::Integer(port)]),\n                        ),\n                        (\"bump\".into(), toml::Value::Boolean(false)),\n                    ])),\n                );","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/daemons/mod.rs#L80-L116","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"# before\n[daemons.postgres]\nversion = \"16\"\n\n# after (preset form)\n[daemons.postgres]\npreset = \"postgres\"\nversion = \"16\"\n\n# or direct form\n[daemons.postgres]\nrun = \"postgres -D data\"","handlingStrategy":"validation","validationCode":"# shell: flag daemons with version/options but no preset\nawk '/^\\[daemons\\./{blk=$0} /version|options/{if (blk !~ /preset/) print blk}' mise.toml","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["config","toml","daemons","validation"],"backgroundTag":"missing-required-config-field","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}