zeroclaw-labs/zeroclaw · error · anyhow::Error

Unknown init system: '{}'. Supported: auto, systemd, openrc

Error message

Unknown init system: '{}'. Supported: auto, systemd, openrc

What it means

InitSystem implements FromStr to parse the --service-init flag. Only 'auto', 'systemd' and 'openrc' (case-insensitive via to_lowercase) are accepted; any other string bails with this message. Surrounding whitespace is not trimmed, so ' systemd' or a value ending in a newline also fails.

Source

Thrown at crates/zeroclaw-runtime/src/service/mod.rs:541

pub enum InitSystem {
    /// Auto-detect based on system indicators
    #[default]
    Auto,
    /// systemd (via systemctl --user)
    Systemd,
    /// OpenRC (via rc-service)
    Openrc,
}

impl FromStr for InitSystem {
    type Err = anyhow::Error;

    fn from_str(s: &str) -> Result<Self> {
        match s.to_lowercase().as_str() {
            "auto" => Ok(Self::Auto),
            "systemd" => Ok(Self::Systemd),
            "openrc" => Ok(Self::Openrc),
            other => bail!(
                "Unknown init system: '{}'. Supported: auto, systemd, openrc",
                other
            ),
        }
    }
}

impl InitSystem {
    #[cfg(target_os = "linux")]
    pub fn resolve(self) -> Result<Self> {
        match self {
            Self::Auto => detect_init_system(),
            concrete => Ok(concrete),
        }
    }

    #[cfg(not(target_os = "linux"))]
    pub fn resolve(self) -> Result<Self> {

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Use exactly one of: auto, systemd, openrc (no surrounding whitespace)
  2. Trim the value before passing it: zeroclaw service install --service-init "$VALUE".trim()
  3. On macOS omit the flag entirely and let auto resolve

Example fix

// before
let init = InitSystem::from_str(&arg)?; // fails on " systemd\n"

// after
let init = InitSystem::from_str(arg.trim())?;
Defensive patterns

Strategy: validation

Validate before calling

fn is_valid_init_system(value: &str) -> bool {
    matches!(value.trim().to_lowercase().as_str(), "auto" | "systemd" | "openrc")
}

Type guard

fn parse_init_system(value: &str) -> Option<InitSystem> {
    match value.trim().to_lowercase().as_str() {
        "auto" => Some(InitSystem::Auto),
        "systemd" => Some(InitSystem::Systemd),
        "openrc" => Some(InitSystem::Openrc),
        _ => None,
    }
}

Prevention

When it happens

Trigger: Passing --service-init a typo or unsupported value such as 'launchd', 'sysvinit', 'upstart', 'SystemD ' (trailing space), or a value read from a config file / env var / script variable that carries whitespace or a newline.

Common situations: Wrapper scripts or CI templates that hardcode an init name borrowed from another tool; assuming macOS launchd is a selectable init; piping values into the flag without trimming.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/6a5d300241d522f7. Report an issue: GitHub.