{"record":{"id":"a54bf69b3d13cce2","repo":"jdx/mise","slug":"user-service-is-also-declared-in-bootstrap-l","errorCode":null,"errorMessage":"user service '{}' is also declared in [bootstrap.linux.systemd.units]; declare it once","messagePattern":"user service '(.+?)' is also declared in \\[bootstrap\\.linux\\.systemd\\.units\\]; declare it once","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/user_services.rs","lineNumber":281,"sourceCode":"\n/// Every user-scope service, validated, with names that collide with\n/// `[bootstrap.linux.systemd.units]` or `[bootstrap.macos.launchd.agents]`\n/// rejected (both would write the same unit or plist).\npub(crate) fn requests_from_config(config: &Config) -> Result<Vec<UserServiceRequest>> {\n    let requests = compose_user_declarations(config)?\n        .into_iter()\n        .map(|(name, (declaration, origin))| {\n            UserServiceRequest::from_toml(name, declaration, Some(origin))\n        })\n        .collect::<Result<Vec<_>>>()?;\n    if requests.is_empty() {\n        return Ok(requests);\n    }\n    let units = crate::system::systemd_from_config(config);\n    let agents = crate::system::launchd_from_config(config);\n    for request in &requests {\n        if units.iter().any(|unit| unit.name == request.name) {\n            bail!(\n                \"user service '{}' is also declared in [bootstrap.linux.systemd.units]; declare it once\",\n                request.name\n            );\n        }\n        if agents.iter().any(|agent| agent.name == request.name) {\n            bail!(\n                \"user service '{}' is also declared in [bootstrap.macos.launchd.agents]; declare it once\",\n                request.name\n            );\n        }\n    }\n    Ok(requests)\n}\n\n/// The mise executable a service definition may reference: the running\n/// binary unless it lives in a temporary or remote-bootstrap staging\n/// directory, else a `mise` on `PATH` outside those. Durability is judged\n/// by where the binary really is, but the path kept is the one found: a","sourceCodeStart":263,"sourceCodeEnd":299,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/user_services.rs#L263-L299","documentation":"A user service name may not collide with a systemd unit declared in `[bootstrap.linux.systemd.units]`. `requests_from_config` cross-checks user service requests against declared system units and fails on duplicates, since managing the same name in two places would create conflicting definitions.","triggerScenarios":"`requests_from_config` finds a user service request whose `name` equals a unit `name` in the systemd units config (src/system/user_services.rs:281).","commonSituations":"Migrating a service from system-level to user-level (or vice versa) and leaving both declarations; duplicating an entry while reorganizing bootstrap config.","solutions":["Delete one of the two declarations (keep the user service or the systemd unit, not both)","Rename one of them if both are genuinely intended to be different services"],"exampleFix":"// before\n[[bootstrap.linux.systemd.units]]\nname = \"my-agent\"\ncommand = \"my-agent\"\n[[bootstrap.linux.user_services]]\nname = \"my-agent\"\ncommand = \"my-agent\"\n\n// after\n[[bootstrap.linux.user_services]]\nname = \"my-agent\"\ncommand = \"my-agent\"","handlingStrategy":"validation","validationCode":"function validateNoDupes(cfg) {\n  const unitNames = new Set((cfg.bootstrap?.linux?.systemd?.units ?? []).map(u => u.name));\n  for (const s of cfg.bootstrap?.linux?.user_services ?? []) {\n    if (unitNames.has(s.name)) throw new Error(`user service '${s.name}' duplicates a systemd unit`);\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep a single source of truth per service name","Search the whole config for a name before adding a new service entry"],"tags":["config","duplicate","systemd","user-services"],"backgroundTag":"conflicting-config-options","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}