{"record":{"id":"b09b70d1c09a19f9","repo":"jdx/mise","slug":"user-service-name-on-change-only-applies-to","errorCode":null,"errorMessage":"user service '{name}': `on_change` only applies to system services","messagePattern":"user service '(.+?)': `on_change` only applies to system services","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/user_services.rs","lineNumber":89,"sourceCode":"        Self::from_toml_with_executable(name, config, origin, durable_mise_executable())\n    }\n\n    fn from_toml_with_executable(\n        name: String,\n        config: ServiceTomlConfig,\n        origin: Option<ResourceOrigin>,\n        executable: Option<PathBuf>,\n    ) -> Result<Self> {\n        if !valid_name(&name) {\n            bail!(\n                \"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                    );","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/user_services.rs#L71-L107","documentation":"The `on_change` option (restart/reload behavior when the definition changes) is only meaningful for system-level services. Setting a non-default `on_change` on a user service is rejected at parse time because user service management does not implement change-action hooks.","triggerScenarios":"A user service entry with `on_change` set to anything other than the default value, parsed via `from_toml_with_executable` at src/system/user_services.rs:89.","commonSituations":"Mirroring a system `[bootstrap.linux.systemd.units]` service block into a user service block and keeping its `on_change` key; assuming user and system services share the same option surface.","solutions":["Remove the `on_change` key from the user service entry","Move the service to `[bootstrap.linux.systemd.units]` if you need `on_change` behavior","Leave `on_change` unset to use the default"],"exampleFix":"// before\n[[bootstrap.linux.user_services]]\nname = \"my-agent\"\ncommand = \"my-agent --daemon\"\non_change = \"restart\"\n\n// after\n[[bootstrap.linux.user_services]]\nname = \"my-agent\"\ncommand = \"my-agent --daemon\"","handlingStrategy":"validation","validationCode":"fn validate_user_service(s: &UserServiceConfig) -> Result<(), String> {\n    if s.on_change != Default::default() {\n        return Err(format!(\"user service '{}': on_change only applies to system services\", s.name));\n    }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep user service entries minimal; do not reuse system unit options","Check which options each service kind supports before adding them"],"tags":["config","validation","user-services"],"backgroundTag":"unsupported-config-value","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"}