jdx/mise · error
service unit ' ' must set a non-empty `exec_start
Error message
service unit '{name}' must set a non-empty `exec_start` What it means
from_toml requires that every service-kind systemd unit defines exec_start with non-empty (after trimming whitespace) content, since a systemd service without ExecStart is invalid. Timer units are exempt — they only need a scheduling directive.
Solutions
- Add a non-empty exec_start to the unit's TOML config (e.g. exec_start = "/usr/bin/myapp --serve")
- If the entry is meant to be a timer, add a schedule key (on_boot_sec, on_calendar, etc.) so it is classified as a Timer
- Remove the unit entry entirely if it is unused
- Trim stray whitespace-only values from exec_start
Example fix
# before (mise.toml) [systemd."myapp.service"] # exec_start commented out # after [systemd."myapp.service"] exec_start = "/usr/local/bin/myapp --serve"
Defensive patterns
Strategy: validation
Validate before calling
// pre-validate a service entry before writing config
if schedule_keys.is_empty() && exec_start.as_deref().map(str::trim).unwrap_or("").is_empty() {
bail!("service needs a non-empty exec_start (or schedule keys to be a timer)");
} Prevention
- Always pair every service unit with an exec_start line in the TOML block
- Don't leave exec_start = "" as a placeholder — remove the whole entry instead
- Remember timer-kind detection depends on schedule keys; add them if you meant a timer
When it happens
Trigger: Defining a service unit in mise.toml without an exec_start key, or with exec_start = "" or whitespace-only value, then loading the systemd config through SystemdRequest::from_toml.
Common situations: Writing a timer entry but leaving service fields out of a service block; commenting out exec_start during debugging; copy-pasting a timer template for a service; intending a timer but not setting any schedule field so it defaults to Service kind.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- timer unit ' ' must set at least one of `on_boot_sec`…
- bootstrap service ' ' sets , which only applies to `scope =…
- managed path ' ' notifies user-scope bootstrap service ' '…
- service unit ' ' has invalid `nice` value ; expected -20…
- timer unit ' ' cannot set service-only directive(s)
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/63d2d39efe0d045d.
Report an issue: GitHub.
Appendix: source
Thrown at src/system/systemd.rs:176
if !valid_name(&name) {
bail!("unit name '{name}' must contain only letters, numbers, '.', '_', '-', or '@'");
}
let is_timer = config.on_boot_sec.is_some()
|| config.on_unit_active_sec.is_some()
|| config.on_unit_inactive_sec.is_some()
|| config.on_calendar.is_some()
|| config.randomized_delay_sec.is_some()
|| config.accuracy_sec.is_some()
|| config.persistent.is_some()
|| config.unit.is_some();
let kind = if is_timer {
SystemdUnitKind::Timer
} else {
SystemdUnitKind::Service
};
let exec_start = config.exec_start.map(|s| s.trim().to_string());
if kind == SystemdUnitKind::Service && exec_start.as_deref().is_none_or(str::is_empty) {
bail!("service unit '{name}' must set a non-empty `exec_start`");
}
if kind == SystemdUnitKind::Timer {
let service_only_fields = [
(exec_start.is_some(), "exec_start"),
(config.service_type.is_some(), "type"),
(config.remain_after_exit.is_some(), "remain_after_exit"),
(config.exec_stop.is_some(), "exec_stop"),
(config.timeout_start_sec.is_some(), "timeout_start_sec"),
(config.timeout_stop_sec.is_some(), "timeout_stop_sec"),
(config.no_new_privileges.is_some(), "no_new_privileges"),
(config.private_tmp.is_some(), "private_tmp"),
(!config.environment.is_empty(), "environment"),
(!config.environment_file.is_empty(), "environment_file"),
(config.nice.is_some(), "nice"),
(config.umask.is_some(), "umask"),
(config.working_directory.is_some(), "working_directory"),
(config.restart.is_some(), "restart"),
(config.restart_sec.is_some(), "restart_sec"),View on GitHub (pinned to 533346cc37)