jdx/mise · error
nix failed: Nix bootstrap requires modern `nix profile`…
Error message
nix {} failed: {}
Nix bootstrap requires modern `nix profile` support and the nix-command and flakes experimental features. Enable these in your Nix configuration; mise does not change it. What it means
mise runs read-only `nix` queries (e.g. `nix config show --json`, `nix profile list --json`, `nix eval --json ...`) through `query()`. When the nix subprocess exits non-zero, mise wraps the captured stderr in this message pointing at the two usual root causes: missing modern `nix profile` support and disabled experimental features (`nix-command`, `flakes`). mise deliberately does not mutate the user's Nix configuration.
Solutions
- Enable the experimental features: add `experimental-features = nix-command flakes` to `~/.config/nix/nix.conf` (or `/etc/nix/nix.conf`).
- Upgrade Nix to 2.24+ so modern `nix profile` exists.
- Run the failing command shown in the message manually to see the underlying Nix diagnostic.
- If `nix eval --offline` fails on registry lookups, warm the registry cache once online or use explicit flake URLs instead of registry names.
- Check NIX_CONFIG / nix.conf in CI images; the environment mise runs in may differ from your shell.
Example fix
# before (nix.conf) # (no experimental-features line) # after experimental-features = nix-command flakes
Defensive patterns
Strategy: validation
Validate before calling
# ensure features before relying on nix-backed installs grep -q 'experimental-features' ~/.config/nix/nix.conf || \ echo 'experimental-features = nix-command flakes' >> ~/.config/nix/nix.conf nix --version # require >= 2.24
Try / catch
async fn run_query(args: &[&str]) -> Result<String> {
query(args).await.map_err(|e| {
eprintln!("hint: enable nix-command and flakes, upgrade Nix >= 2.24");
e
})
} Prevention
- Set experimental-features = nix-command flakes in nix.conf
- Keep Nix >= 2.24 on all machines and CI
- Run `nix profile list --json` manually to verify the environment mise will see
- Beware CI images with different nix.conf than your shell
When it happens
Trigger: Any `nix` invocation in `query()` fails: experimental features not enabled (`nix-command`/`flakes`), no `nix profile` support (very old Nix), bad profile path, registry resolution failure, or `nix eval --impure` disallowed by config.
Common situations: Fresh Nix installs without `experimental-features = nix-command flakes` in nix.conf; single-user Nix on distros with ancient versions; sandboxed CI where nix.conf is not the user's; `--offline` eval failing due to missing flake registry cache.
Understand the failure class
Background: "git command failed": what it means when a tool shells out to git and git exits non-zero — this error's family across 21 libraries.
Related errors
- nix failed; see Nix's diagnostic above. Ensure nix-command…
- mas install failed
- mas list failed
- mas upgrade failed
- pacman -Qi failed
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/0234806f0e7298c1.
Report an issue: GitHub.
Appendix: source
Thrown at src/system/packages/nix.rs:137
refs: Vec<Value>,
}
#[derive(Clone)]
struct MatchedEntry {
name: String,
paths: Vec<String>,
}
async fn query(args: &[&str]) -> Result<String> {
debug!("$ nix {}", shell_words::join(args));
let output = tokio::process::Command::new("nix")
.args(args)
.stdin(Stdio::null())
.output()
.await
.wrap_err("failed to run Nix; install Nix and make its CLI available on PATH")?;
if !output.status.success() {
bail!(
"nix {} failed: {}\nNix bootstrap requires modern `nix profile` support and the nix-command and flakes experimental features. Enable these in your Nix configuration; mise does not change it.",
shell_words::join(args),
String::from_utf8_lossy(&output.stderr).trim()
);
}
Ok(String::from_utf8(output.stdout)?)
}
/// Passing an explicit profile avoids Nix's default-profile initialization:
/// even `nix profile list` otherwise creates ~/.nix-profile on a fresh home.
async fn profile_path() -> Result<PathBuf> {
let config: Value = serde_json::from_str(&query(&["config", "show", "--json"]).await?)?;
let xdg = config["use-xdg-base-directories"]["value"]
.as_bool()
.unwrap_or(false);
Ok(if xdg {
std::env::var_os("XDG_STATE_HOME")
.filter(|p| !p.is_empty())View on GitHub (pinned to 533346cc37)