zeroclaw-labs/zeroclaw · error · anyhow::Error
Linux service {action} only manages the default zeroclaw ser
Error message
Linux service {action} only manages the default zeroclaw service. Config directory {config_dir} maps to named service {service}; provide that unit manually, then use service status/start/stop/restart/logs to manage it. What it means
On Linux, install/uninstall only manage the default zeroclaw systemd unit. ensure_linux_default_install_scope derives the service name from the config directory; a non-default directory maps to a named service which the installer refuses to create, so it bails and tells you to provide that unit manually.
Source
Thrown at crates/zeroclaw-runtime/src/service/mod.rs:639
format!("{}.service", linux_service_base(config))
}
fn linux_openrc_service(config: &Config) -> String {
linux_service_base(config)
}
fn ensure_linux_default_install_scope(config: &Config, action: &str) -> Result<()> {
let service = linux_service_base(config);
if service == "zeroclaw" {
return Ok(());
}
let config_dir = config
.config_path
.parent()
.map(|path| path.display().to_string())
.unwrap_or_else(|| config.config_path.display().to_string());
bail!(
"Linux service {action} only manages the default zeroclaw service. \
Config directory {config_dir} maps to named service {service}; \
provide that unit manually, then use service status/start/stop/restart/logs to manage it."
);
}
fn linux_systemd_action_args(config: &Config, action: &str) -> Vec<String> {
vec![
"--user".to_string(),
action.to_string(),
linux_systemd_unit(config),
]
}
fn linux_openrc_action_args(config: &Config, action: &str) -> Vec<String> {
vec![linux_openrc_service(config), action.to_string()]
}
View on GitHub (pinned to 88bb9c8533)
Solutions
- Run install/uninstall with the default config directory (~/.config/zeroclaw) for the service-managed instance
- Or drop the named unit in yourself (zeroclaw@<name>.service template under ~/.config/systemd/user/) and manage it via 'zeroclaw service status/start/stop/restart/logs' with that config dir
- Reserve per-instance config dirs for manually provisioned units only
Example fix
# before ZEROCLAW_CONFIG_DIR=~/.config/zeroclaw-second zeroclaw service install # after: provide the named unit manually, then manage it cp zeroclaw@.service ~/.config/systemd/user/ ZEROCLAW_CONFIG_DIR=~/.config/zeroclaw-second zeroclaw service start
Defensive patterns
Strategy: validation
Validate before calling
fn manages_default_scope_only(config: &Config) -> bool {
let dir = config.config_path.parent().map(|p| p.to_path_buf());
let home = std::env::var("HOME").unwrap_or_default();
dir == Some(std::path::Path::new(&home).join(".config").join("zeroclaw"))
} Prevention
- Invoke service install/uninstall only with the default config directory
- Template the named systemd unit yourself for extra instances
- Document which config dirs are service-managed versus manually managed
When it happens
Trigger: Running 'zeroclaw service install' or 'zeroclaw service uninstall' on Linux while the config path (e.g. via ZEROCLAW_CONFIG_DIR or --config) lives in a non-default directory such as ~/.config/zeroclaw-second that maps to a named zeroclaw@<name> service.
Common situations: Running multiple zeroclaw instances from separate config dirs; automation that reuses one custom config path across hosts; CI pipelines setting a config dir before installing.
Related errors
- systemd user lingering disabled; user service may stop after
- systemctl restart failed: {}
- the OpenRC log writer is only supported on Linux
- Could not detect init system. Supported: systemd, OpenRC. Us
- journalctl exited with non-zero status
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/71608aca61df94c9.
Report an issue: GitHub.