Skip to content

Fix: mise Not Working — Shell Activation, .tool-versions, Plugin Install, and Python venv

FixDevs ·

Quick Answer

How to fix mise (formerly rtx) errors — activation hook not running, tool not found after install, .tool-versions vs .mise.toml, Python venv integration, idiomatic env loading, and trust prompts.

The Error

You install mise but node still resolves to the system version:

$ mise install node@20
$ node --version
v18.10.0   # System Node — mise's Node 20 isn't being picked up.

Or mise install succeeds but which can’t find the binary:

$ mise install [email protected]
$ which python
python not found

Or .tool-versions is ignored:

# .tool-versions
node 20.18.0
python 3.12.7
$ cd my-project
$ node --version
v18.10.0   # Should be 20.18.0

Or you get repeated “trust” prompts on every directory change:

mise WARN The config file is not trusted. You can trust it with:
  mise trust /path/to/.mise.toml

Why This Happens

mise is a polyglot version manager that replaces asdf, nvm, pyenv, rbenv, and others. It installs tools into ~/.local/share/mise/ and uses a shim or PATH activation to expose them. Most failures come from:

  • Shell activation isn’t loaded. Without mise activate running in your shell init, PATH doesn’t include mise’s tools. mise install works, but the tool isn’t on your PATH.
  • .tool-versions and .mise.toml are both supported, with .mise.toml taking precedence. Projects with both can get confused — usually the .mise.toml wins silently.
  • Project trust. mise refuses to load config from untrusted directories (a security feature against malicious repos with pre-execute hooks). You must mise trust once per project.
  • Plugin name conflicts. Some tools (python, nodejs) have core plugins built in; others come from asdf compatibility. Mismatches cause “no such plugin” errors.

Fix 1: Activate mise in Your Shell

Add to your shell init:

Bash (~/.bashrc):

eval "$(mise activate bash)"

Zsh (~/.zshrc):

eval "$(mise activate zsh)"

Fish (~/.config/fish/config.fish):

mise activate fish | source

PowerShell ($PROFILE):

mise activate pwsh | Out-String | Invoke-Expression

Open a new terminal (or source ~/.zshrc). Verify:

$ which node
/home/you/.local/share/mise/installs/node/20.18.0/bin/node

which node should point at mise’s install directory, not /usr/bin/node.

Pro Tip: Use the --shims mode if mise activate interferes with your shell setup:

# Add the shim dir to PATH (in your shell init):
export PATH="$HOME/.local/share/mise/shims:$PATH"

Shim mode is slower (each command exec’d through a wrapper) but works in non-interactive shells, scripts, and IDEs that don’t load your shell rc files.

Fix 2: Install Tools

After activation:

mise install node@20         # Install latest 20.x
mise install [email protected]    # Pin to exact version
mise install [email protected]     # Latest 3.12.x
mise install rust@latest     # Latest stable
mise install [email protected]

To install everything declared in the current project:

cd my-project
mise install
# Reads .mise.toml / .tool-versions and installs all listed tools.

To set a tool version for the current directory:

mise use node@20        # Adds to .mise.toml in this directory
mise use --global node@20   # Adds to ~/.config/mise/config.toml (default everywhere)

To list installed:

mise list
# node    20.18.0   ~/.config/mise/config.toml
# python  3.12.7    ~/projects/my-app/.mise.toml

Fix 3: .mise.toml vs .tool-versions

.mise.toml (preferred):

[tools]
node = "20.18.0"
python = "3.12.7"
go = "1.23"
rust = { version = "stable", profile = "minimal" }

[env]
DATABASE_URL = "postgres://localhost/myapp"
NODE_ENV = "development"

[tasks.dev]
run = "npm run dev"

[tasks.test]
run = "npm test"

.tool-versions (asdf-compatible):

node 20.18.0
python 3.12.7
go 1.23

mise reads both, with .mise.toml winning if both exist. Use .mise.toml for new projects — it supports env vars and tasks that .tool-versions doesn’t.

For team consistency, commit both — older devs on asdf see .tool-versions, mise users get the richer .mise.toml. Set them to identical versions to avoid drift.

Common Mistake: Editing .tool-versions and assuming mise picked it up. If a .mise.toml exists with different versions, it wins. Run mise list to see what mise actually resolved.

Fix 4: Trust the Project

The first time you cd into a directory with .mise.toml, mise prompts:

mise WARN The config file is not trusted. You can trust it with:
  mise trust /path/to/.mise.toml

Trust the file:

mise trust

This adds the path to ~/.local/share/mise/trusted-configs/. Now mise loads it without prompting.

For CI environments where you can’t interactively trust:

mise trust --all   # In CI scripts before any mise operation.
# Or:
MISE_TRUSTED_CONFIG_PATHS="/path/to/repo" mise install

Note: Trust is a real security control. If a repo’s .mise.toml has pre_install hooks or [env] blocks that execute shell, you don’t want them running automatically on clone. The prompt is one-time per file.

Fix 5: Python venv Integration

mise can auto-create and activate a venv per project:

# .mise.toml
[tools]
python = "3.12.7"

[env]
_.python.venv = { path = ".venv", create = true }

Now cd into the project and mise creates .venv automatically. Any python or pip you run uses that venv.

For uv:

[tools]
python = "3.12.7"
uv = "latest"

[env]
_.python.venv = { path = ".venv", create = true, uv_create_args = ["--seed"] }

For poetry, the venv is managed by poetry — don’t use mise’s venv feature. Just install python via mise:

[tools]
python = "3.12.7"
poetry = "latest"

Pro Tip: Pin both Python and the package manager (uv/poetry) in .mise.toml. Avoids “works on my machine” issues when a teammate has a different poetry version.

Fix 6: Plugin Conflicts and Aliases

Some tools have built-in core plugins (node, python, go, rust). Others come from asdf:

mise plugins ls       # Show installed plugins
mise plugins ls --core   # Show built-in

To install an asdf-compatible plugin:

mise plugins install awscli https://github.com/MetricMike/asdf-awscli.git
mise install [email protected]

For tool aliases (using a different name):

[tools]
nodejs = "20"   # mise treats "nodejs" as alias for "node"

Common Mistake: Installing both python (core) and python (asdf plugin). Pick one. Remove the asdf plugin: mise plugins uninstall python and let the core plugin handle it.

Fix 7: Environment Variables

.mise.toml’s [env] block sets env vars per project:

[env]
DATABASE_URL = "postgres://localhost/dev"
NODE_OPTIONS = "--enable-source-maps"
PATH = "./node_modules/.bin:$PATH"   # Note: $PATH refers to env var

Strings starting with $ reference other env vars. For literal $, escape: \$.

For sensitive values, load from a file:

[env]
_.file = ".env"

This reads .env (gitignored) and exposes its values. mise enforces “trusted file” rules — the .env file’s path must be under a trusted config root.

For derived env from tools:

[env]
_.python.venv = { path = ".venv" }   # Sets VIRTUAL_ENV, prepends PATH

Use mise env to see what mise would inject:

mise env
# export DATABASE_URL=postgres://...
# export VIRTUAL_ENV=/path/to/.venv
# ...

Fix 8: Tasks (Built-in Task Runner)

.mise.toml can define tasks (like Makefile + npm scripts):

[tasks.dev]
description = "Run dev server"
run = "npm run dev"

[tasks.test]
description = "Run tests"
run = "npm test"
depends = ["build"]

[tasks.build]
description = "Build the project"
run = "tsc -p ."

[tasks.deploy]
description = "Deploy to prod"
run = """
npm run build
npm run test
fly deploy
"""

Run with:

mise run dev
mise run test     # Runs build first due to depends
mise tasks ls     # List all tasks

The depends field gives you Make-like dependency chains across tools without a separate Makefile.

Pro Tip: Standardize on mise run <task> across your team. New contributors don’t need to learn each project’s scripts — mise tasks ls is self-documenting.

Still Not Working?

A few less-obvious failures:

  • mise: command not found. Install didn’t add mise to PATH. Re-run the installer or add ~/.local/bin (mise’s default install location) to PATH.
  • mise activate triggers errors in non-interactive shells. Use eval "$(mise activate bash --shims)" or set MISE_SHIMS_DIR to a known path.
  • VS Code terminal doesn’t see mise tools. Two causes: (1) VS Code doesn’t load your .zshrc. Set "terminal.integrated.profiles.osx" / "linux" to bash --login or similar. (2) Use shim mode (PATH-based) which works regardless of shell init.
  • Pre-commit hooks run system Node instead of mise Node. Hooks run in a minimal shell. Either configure the hook to source mise activation, or use mise’s shim mode globally.
  • mise install hangs on a tool. Some plugins download from slow upstreams (Python downloads from python.org; Ruby builds from source). Use MISE_INSTALL_LOG_LEVEL=debug to see what’s happening.
  • CI cache misses every run. Cache ~/.local/share/mise between CI runs to avoid re-installing. GitHub Actions: actions/cache@v4 with ~/.local/share/mise as the path.
  • mise outdated doesn’t catch security updates. It compares against the latest version available. For CVE tracking, use a separate tool like npm audit, cargo audit, etc.
  • Conflicts with asdf. If you migrated from asdf, remove ~/.asdf and any asdf lines from your shell rc. mise reads ~/.tool-versions natively.

For related toolchain and version-manager issues, see Python virtualenv wrong python, pip externally-managed-environment, uv not working, and Node cannot find module.

F

FixDevs

Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.

Was this article helpful?

Related Articles