jdx/mise · error
conflicting bootstrap service declarations for
Error message
conflicting bootstrap service declarations for {name}
first:
{}
second:
{} What it means
The same bootstrap service name is declared in multiple config files with differing definitions. mise composes declarations across layered config files; when two declarations for a name differ (the `ServiceDeclaration` values are unequal), it refuses to silently pick one and reports both source locations.
Solutions
- Delete or update one of the duplicate declarations so they match
- Keep the service only in the most specific config file (project-level)
- If an override is intended, remove the base declaration rather than redefining the name
Example fix
# before: global ~/.config/mise/config.toml AND project mise.toml both define [services.myapp] differently # after: keep only one definition, in project mise.toml [services.myapp] command = "./scripts/serve.sh"
Defensive patterns
Strategy: validation
Validate before calling
grep -rn '\[services\.' ~/.config/mise/ ./mise.toml ./config/ # find duplicate service names across layers
Prevention
- Define each bootstrap service in exactly one config file
- Audit layered configs (global vs project) for duplicate [services.*] tables
- Treat a legitimate override as a removal of the base declaration
When it happens
Trigger: `compose_declarations` iterates `config.bootstrap_config_maps()` and finds an existing entry for a name whose declaration differs from the new one — e.g. the same service defined in both the global and a project mise.toml with different commands.
Common situations: A project mise.toml overriding a global bootstrap service with a different command; team config merged with personal config; a stale duplicate left in an included config file.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- bootstrap service ' ' cannot be both masked and running
- bootstrap service ' ' cannot be both masked and enabled
- conflicting bootstrap secret declarations for
- conflicting bootstrap service declarations for
- conflicting dotfile declarations for
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/9812c33b84b5d115.
Report an issue: GitHub.
Appendix: source
Thrown at src/system/services_common.rs:251
/// Names of every user-scope service, for notification validation.
pub(crate) fn user_service_names(config: &Config) -> Result<Vec<String>> {
Ok(compose_user_declarations(config)?.into_keys().collect())
}
/// `[bootstrap.services]` from every config map, rejecting redeclarations that
/// disagree.
pub(crate) fn compose_declarations(
config: &Config,
) -> Result<IndexMap<String, (ServiceTomlConfig, ResourceOrigin)>> {
let mut composed: IndexMap<String, (ServiceTomlConfig, ResourceOrigin)> = IndexMap::new();
for config_files in config.bootstrap_config_maps() {
for (name, declaration) in services_from_config_files(config_files) {
if let Some(existing) = composed.get(&name) {
if existing.0 == declaration.0 {
continue;
}
bail!(
"conflicting bootstrap service declarations for {name}\n\n first:\n {}\n\n second:\n {}",
existing.1.conflict_description(),
declaration.1.conflict_description(),
);
}
composed.insert(name, declaration);
}
}
Ok(composed)
}
fn services_from_config_files(
config_files: &ConfigMap,
) -> IndexMap<String, (ServiceTomlConfig, ResourceOrigin)> {
let mut merged = IndexMap::new();
for (path, cf) in config_files {
if let Some(bootstrap) = cf.bootstrap_config() {
let origin = ResourceOrigin {View on GitHub (pinned to 533346cc37)