jdx/mise · error
user service '{}' is also declared in [bootstrap.macos.launc
Error message
user service '{}' is also declared in [bootstrap.macos.launchd.agents]; declare it once What it means
A user service name may not collide with a launchd agent declared in `[bootstrap.macos.launchd.agents]`. `requests_from_config` fails on the duplicate to avoid two managers fighting over the same service name.
Source
Thrown at src/system/user_services.rs:287
.into_iter()
.map(|(name, (declaration, origin))| {
UserServiceRequest::from_toml(name, declaration, Some(origin))
})
.collect::<Result<Vec<_>>>()?;
if requests.is_empty() {
return Ok(requests);
}
let units = crate::system::systemd_from_config(config);
let agents = crate::system::launchd_from_config(config);
for request in &requests {
if units.iter().any(|unit| unit.name == request.name) {
bail!(
"user service '{}' is also declared in [bootstrap.linux.systemd.units]; declare it once",
request.name
);
}
if agents.iter().any(|agent| agent.name == request.name) {
bail!(
"user service '{}' is also declared in [bootstrap.macos.launchd.agents]; declare it once",
request.name
);
}
}
Ok(requests)
}
/// The mise executable a service definition may reference: the running
/// binary unless it lives in a temporary or remote-bootstrap staging
/// directory, else a `mise` on `PATH` outside those. Durability is judged
/// by where the binary really is, but the path kept is the one found: a
/// Homebrew or package-manager symlink survives an upgrade, the versioned
/// file behind it does not.
pub(crate) fn durable_mise_executable() -> Option<PathBuf> {
let current = crate::env::MISE_BIN.clone();
if durable_behind(¤t) {
return Some(current);View on GitHub (pinned to afd2eddd3a)
Solutions
- Keep only one declaration: either the launchd agent or the user service
- Rename one if they are truly distinct services
Example fix
// before [[bootstrap.macos.launchd.agents]] name = "my-agent" command = "my-agent" [[bootstrap.macos.user_services]] name = "my-agent" command = "my-agent" // after [[bootstrap.macos.launchd.agents]] name = "my-agent" command = "my-agent"
Defensive patterns
Strategy: validation
Validate before calling
function validateNoLaunchdDupes(cfg) {
const agentNames = new Set((cfg.bootstrap?.macos?.launchd?.agents ?? []).map(a => a.name));
for (const s of cfg.bootstrap?.macos?.user_services ?? []) {
if (agentNames.has(s.name)) throw new Error(`user service '${s.name}' duplicates a launchd agent`);
}
} Prevention
- When sharing config across macOS/Linux, declare each service once per host-appropriate mechanism
- Grep for the service name across all bootstrap tables before adding entries
When it happens
Trigger: `requests_from_config` finds a user service request whose `name` matches a launchd agent name (src/system/user_services.rs:287).
Common situations: Sharing one config file across Linux and macOS and declaring the same service both as a launchd agent and a user service; leftover entries after switching service mechanisms.
Related errors
- user service '{}' is also declared in [bootstrap.linux.syste
- mise oci does not support [bootstrap.macos.*] defaults (foun
- [dotfiles]: duplicate OCI file path {path:?}
- conflicting dotfile edit declarations for {}/{} first:
- `launchctl {}` failed: {}
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/65b4b9d0251bee3f.
Report an issue: GitHub.