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

  1. Delete or update one of the duplicate declarations so they match
  2. Keep the service only in the most specific config file (project-level)
  3. 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

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


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)