jdx/mise · error

cannot remove user service

Error message

cannot remove user service '{name}': {}

What it means

After name validation, `remove_named` checks whether a user service manager is available on the current platform (systemd on Linux, launchd on macOS). If `is_available()` returns false, it bails with the manager-specific reason from `unavailable_reason()`, since no removal can be performed.

Solutions

  1. Enable systemd (e.g. [boot] systemd=true in /etc/wsl.conf on WSL2, then reboot the distro)
  2. Start the systemd user session: `systemctl --user` should work; ensure DBUS_SESSION_BUS_ADDRESS/XDG_RUNTIME_DIR are set
  3. Remove the service definition manually (delete the unit/plist file) if no service manager is available
  4. Run the removal on the platform where the service is actually installed
Defensive patterns

Strategy: fallback

Validate before calling

# verify a usable user service manager before attempting removal
systemctl --user is-system-running 2>/dev/null || echo "systemd user session unavailable"

Try / catch

try {
  await run(['mise', 'user-service', 'remove', name]);
} catch (e) {
  console.warn('service manager unavailable; removing definition file manually');
  await run(['rm', '-f', `~/.config/systemd/user/${name}.service`]);
}

Prevention

When it happens

Trigger: Calling remove_named on a platform without the expected init system — e.g. systemd missing/not running (containers, WSL1 without systemd, minimal images) — or running a macOS-targeted flow where launchd access fails.

Common situations: Running `mise user-service remove` inside a Docker container or CI job with no systemd user session, or on WSL setups where systemd is disabled in /etc/wsl.conf.

Understand the failure class

Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.

Related errors


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/d860825524e587e5. Report an issue: GitHub.

Appendix: source

Thrown at src/system/user_services.rs:740

        // an apply boots the agent out and back in, which restarts it
        launchd::apply(&[request.launchd_request()?], dry_run).await
    } else {
        // Task Scheduler keeps a running instance across an unchanged
        // registration, so a forced restart has to end and run it
        let mut task = request.scheduled_task_request();
        task.restart = restart == Restart::Forced;
        scheduled_tasks::apply(&[task], dry_run).await
    }
}

/// Remove the installed definition for `name`, declared or not. Returns
/// whether one existed.
pub(crate) async fn remove_named(name: &str, dry_run: bool) -> Result<bool> {
    if !valid_name(name) {
        bail!("user service name '{name}' must contain only letters, numbers, '.', '_', or '-'");
    }
    if !is_available() {
        bail!(
            "cannot remove user service '{name}': {}",
            unavailable_reason()
        );
    }
    if cfg!(target_os = "linux") {
        systemd::remove_service(name, dry_run).await
    } else if cfg!(target_os = "macos") {
        launchd::remove_agent(name, dry_run).await
    } else {
        scheduled_tasks::remove_task(name, dry_run).await
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::system::services_common::ServiceScope;

View on GitHub (pinned to 533346cc37)