jdx/mise · error

daemon requires @ ( ), but [tools] selects

Error message

daemon {} requires {tool}@{version} ({}), but [tools] selects {}

What it means

When the toolset's selected version for a daemon's tool does not satisfy the daemon's pinned version request, mise resolves the request offline and compares the concrete versions. If the selected version differs from what the daemon requires, it bails explaining exactly which daemon needs which version and what [tools] currently selects. This prevents daemons from silently running against a wrong major/minor of their backing tool.

Solutions

  1. Align the daemon's version pin with [tools]: set both to the same version (e.g. postgres = "16" everywhere).
  2. Run `mise install` so the required version is actually installed, then `mise ls postgres` to verify.
  3. If the daemon pin is stale, update the [daemons] entry to the new version.
  4. Check other config layers (global mise.toml, .tool-versions) that may be overriding the version selection.

Example fix

// before
[tools]
postgres = "17"
[daemons.db]
version = "16"

// after
[tools]
postgres = "17"
[daemons.db]
version = "17"
Defensive patterns

Strategy: validation

Validate before calling

# Ensure [tools] version satisfies the daemon pin before starting
mise ls postgres  # installed version must match the [daemons] version pin

Try / catch

try {
  await mise.daemons.start();
} catch (e) {
  const m = String(e).match(/daemon (\S+) requires (\S+)@(\S+) \((\S+)\), but \[tools\] selects (\S+)/);
  if (m) console.error(`Set ${m[2]} = "${m[3]}" in [tools] (or update the daemon pin).`);
}

Prevention

When it happens

Trigger: validate_tools finds ts.versions for the tool, but the first selected version fails `list_installed_versions_matching(version)` and offline ToolRequest::resolve yields a requested.version != actual.version — e.g. daemon pins postgres@16 while [tools] selects postgres = "17".

Common situations: Upgrading a tool in [tools] without updating the daemon's pinned version, or vice versa; two config files ([tools] in one, daemons in another) drifting apart; a teammate pinning a different major than your installed one.

Related errors


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/18702a3869ebb218. Report an issue: GitHub.

Appendix: source

Thrown at src/daemons/runtime.rs:425

            .contains(&actual.version);
        if compatible {
            continue;
        }
        let requested = ToolRequest::new(
            ba.into(),
            version,
            ToolSource::MiseTomlDaemon(daemon.source.clone()),
        )?
        .resolve(
            config,
            &crate::toolset::ResolveOptions {
                offline: true,
                ..Default::default()
            },
        )
        .await?;
        if actual.version != requested.version {
            bail!(
                "daemon {} requires {tool}@{version} ({}), but [tools] selects {}",
                daemon.name,
                requested.version,
                actual.version
            );
        }
    }
    Ok(())
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    #[cfg(unix)]
    fn symlinked_roots_share_namespace_and_state() {
        let tmp = tempfile::tempdir().unwrap();
        let root = tmp.path().join("project");

View on GitHub (pinned to 533346cc37)