jdx/mise · error
user service '{name}': `on_change` only applies to system se
Error message
user service '{name}': `on_change` only applies to system services What it means
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.
Source
Thrown at src/system/user_services.rs:89
Self::from_toml_with_executable(name, config, origin, durable_mise_executable())
}
fn from_toml_with_executable(
name: String,
config: ServiceTomlConfig,
origin: Option<ResourceOrigin>,
executable: Option<PathBuf>,
) -> Result<Self> {
if !valid_name(&name) {
bail!(
"user service name '{name}' must contain only letters, numbers, '.', '_', or '-'"
);
}
if config.masked {
bail!("user service '{name}' cannot be masked; use `state = \"absent\"` to remove it");
}
if config.on_change != super::services_common::ServiceChangeAction::default() {
bail!("user service '{name}': `on_change` only applies to system services");
}
let mut description = config.description;
let mut restart = config.restart;
let mut nice = None;
let mut unresolved = None;
let command = match (config.builtin.as_deref(), config.command.as_deref()) {
(Some(_), Some(_)) => {
bail!("user service '{name}' sets both `builtin` and `command`; choose one")
}
(None, None) => {
bail!("user service '{name}' must set `command` or `builtin`")
}
(Some(builtin_name), None) => {
let Some(definition) = builtin(builtin_name) else {
bail!(
"user service '{name}' names unknown builtin '{builtin_name}'; available: {}",
BUILTIN_NAMES.join(", ")
);View on GitHub (pinned to afd2eddd3a)
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
Example fix
// before [[bootstrap.linux.user_services]] name = "my-agent" command = "my-agent --daemon" on_change = "restart" // after [[bootstrap.linux.user_services]] name = "my-agent" command = "my-agent --daemon"
Defensive patterns
Strategy: validation
Validate before calling
fn validate_user_service(s: &UserServiceConfig) -> Result<(), String> {
if s.on_change != Default::default() {
return Err(format!("user service '{}': on_change only applies to system services", s.name));
}
Ok(())
} Prevention
- Keep user service entries minimal; do not reuse system unit options
- Check which options each service kind supports before adding them
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- user service '{name}' cannot be masked; use `state = "absent
- user service '{name}' sets both `builtin` and `command`; cho
- user service '{name}' must set `command` or `builtin`
- user service '{name}' names unknown builtin '{builtin_name}'
- user service '{name}' must set a non-empty `command`
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/b09b70d1c09a19f9.
Report an issue: GitHub.