{"record":{"id":"672c7aedcef98e0d","repo":"jdx/mise","slug":"user-service-name-must-set-command-or-built","errorCode":null,"errorMessage":"user service '{name}' must set `command` or `builtin`","messagePattern":"user service '(.+?)' must set `command` or `builtin`","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/user_services.rs","lineNumber":100,"sourceCode":"                \"user service name '{name}' must contain only letters, numbers, '.', '_', or '-'\"\n            );\n        }\n        if config.masked {\n            bail!(\"user service '{name}' cannot be masked; use `state = \\\"absent\\\"` to remove it\");\n        }\n        if config.on_change != super::services_common::ServiceChangeAction::default() {\n            bail!(\"user service '{name}': `on_change` only applies to system services\");\n        }\n        let mut description = config.description;\n        let mut restart = config.restart;\n        let mut nice = None;\n        let mut unresolved = None;\n        let command = match (config.builtin.as_deref(), config.command.as_deref()) {\n            (Some(_), Some(_)) => {\n                bail!(\"user service '{name}' sets both `builtin` and `command`; choose one\")\n            }\n            (None, None) => {\n                bail!(\"user service '{name}' must set `command` or `builtin`\")\n            }\n            (Some(builtin_name), None) => {\n                let Some(definition) = builtin(builtin_name) else {\n                    bail!(\n                        \"user service '{name}' names unknown builtin '{builtin_name}'; available: {}\",\n                        BUILTIN_NAMES.join(\", \")\n                    );\n                };\n                description.get_or_insert_with(|| definition.description.to_string());\n                restart.get_or_insert(definition.restart);\n                nice = definition.nice;\n                match executable {\n                    Some(exe) => Some(\n                        std::iter::once(quote_program(&exe.to_string_lossy()))\n                            .chain(definition.args.iter().map(|arg| arg.to_string()))\n                            .collect::<Vec<_>>()\n                            .join(\" \"),\n                    ),","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/user_services.rs#L82-L118","documentation":"Definition validation in user services from_toml_with_executable: the service declared neither a `command` nor a `builtin`, so there is nothing to run or manage. Fires on an incomplete user service block in config.","triggerScenarios":"A user service entry with both `builtin` and `command` absent/empty (the `(None, None)` match arm) at src/system/user_services.rs:100 in `from_toml_with_executable`.","commonSituations":"Starting an entry with only a `name` and `state`, intending to fill in the command later; commenting out a command and forgetting the entry still parses.","solutions":["Add a `command = \"...\"` to the entry","Or set `builtin = \"<name>\"` to one of the available built-ins (see BUILTIN_NAMES)","Or remove the entry entirely if not needed"],"exampleFix":"// before\n[[bootstrap.linux.user_services]]\nname = \"my-agent\"\nstate = \"running\"\n\n// after\n[[bootstrap.linux.user_services]]\nname = \"my-agent\"\ncommand = \"my-agent --daemon\"\nstate = \"running\"","handlingStrategy":"validation","validationCode":"fn validate_user_service(s: &UserServiceConfig) -> Result<(), String> {\n    if s.builtin.is_none() && s.command.is_none() {\n        return Err(format!(\"user service '{}': must set command or builtin\", s.name));\n    }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pair a user service `name` with either `command` or `builtin`","Remove stub entries before committing config","Use schema validation on mise.toml to catch missing fields early"],"tags":["config","validation","missing-field","user-services"],"backgroundTag":"missing-required-config-field","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}