fix(task): install monorepo subdir tools before running deps#9454
Conversation
When running a monorepo task from the root via `mise //sub:taskname`, tools declared in `sub/mise.toml` were not installed before auto `[deps]` steps ran. Providers like `[deps.bun] auto=true` then failed with "No such file or directory" because `bun` wasn't on PATH yet. Reorder `Run::run` so `resolve_depends` runs before the toolset is built. The subdirectory config files attached to each resolved task (`task.cf`) are now combined with `config.config_files` and passed to `ToolsetBuilder::with_config_files`, so subdir tools get installed before any deps step runs. The deps engine continues to receive the same subdir configs as before. Fixes #9445 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request fixes a bug in monorepo task execution where tools defined in subdirectory configuration files were not being installed before dependency steps were run. The toolset construction logic in src/cli/run.rs has been moved to follow task resolution, ensuring that all relevant configuration files from sub-tasks are included. Additionally, a regression test has been added to validate that tools from subdirectories are correctly installed and available on the PATH for dependency execution. I have no feedback to provide as there were no review comments.
Greptile SummaryThis PR fixes a monorepo bug where The fix reorders Confidence Score: 5/5Safe to merge — targeted reordering of resolve_depends before toolset build, with no new APIs and a dedicated regression test. No P0 or P1 issues found. The reordering preserves the "no matching task → no tool install" invariant. Config merging via or_insert_with correctly deduplicates root and subdir entries. The test is sourced (not executed) by the runner, so the missing executable bit is harmless. All existing monorepo tests were reported passing. No files require special attention. Important Files Changed
Sequence DiagramsequenceDiagram
participant RunRun as Run::run
participant GTL as get_task_lists
participant RD as resolve_depends
participant TB as ToolsetBuilder
participant IM as install_missing_versions
participant DE as DepsEngine
RunRun->>GTL: get_task_lists(config, args)
GTL-->>RunRun: task_list (with subdir tasks via task.cf)
Note over RunRun: NEW ORDER (after fix)
RunRun->>RD: resolve_depends(config, task_list)
RD-->>RunRun: resolved_tasks (task.cf = sub/mise.toml)
RunRun->>RunRun: collect subdir_configs from task.cf
RunRun->>RunRun: combined_configs = root config_files + subdir_configs
RunRun->>TB: ToolsetBuilder::with_config_files(combined_configs).build()
TB-->>RunRun: ts (includes sub/mise.toml tools e.g. bun/tiny)
RunRun->>IM: ts.install_missing_versions()
Note over IM: Installs bun/tiny BEFORE deps run
RunRun->>DE: DepsEngine::new + add_config_files(subdir_configs)
DE->>DE: engine.run(auto_only=true)
Note over DE: bun/rtx-tiny now on PATH
RunRun->>RunRun: parallelize_tasks(resolved_tasks)
Reviews (1): Last reviewed commit: "fix(task): install monorepo subdir tools..." | Re-trigger Greptile |
Hyperfine Performance
|
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.4.25 x -- echo |
21.6 ± 1.0 | 20.8 | 40.9 | 1.00 |
mise x -- echo |
21.7 ± 0.5 | 20.9 | 25.7 | 1.00 ± 0.05 |
mise env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.4.25 env |
21.1 ± 0.9 | 20.3 | 31.2 | 1.00 ± 0.04 |
mise env |
21.1 ± 0.3 | 20.5 | 22.5 | 1.00 |
mise hook-env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.4.25 hook-env |
21.8 ± 0.7 | 21.0 | 34.6 | 1.00 |
mise hook-env |
21.9 ± 0.4 | 21.1 | 24.8 | 1.00 ± 0.04 |
mise ls
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.4.25 ls |
22.1 ± 0.5 | 21.5 | 26.5 | 1.00 |
mise ls |
22.3 ± 1.0 | 21.3 | 36.3 | 1.01 ± 0.05 |
xtasks/test/perf
| Command | mise-2026.4.25 | mise | Variance |
|---|---|---|---|
| install (cached) | 154ms | 152ms | +1% |
| ls (cached) | 79ms | 78ms | +1% |
| bin-paths (cached) | 79ms | 79ms | +0% |
| task-ls (cached) | 824ms | 801ms | +2% |
### 🚀 Features - **(deps)** add aube provider by @jdx in [#9452](#9452) - **(ls-remote)** add strict metadata mode by @jdx in [#9448](#9448) ### 🐛 Bug Fixes - **(env)** parse concatenated short form `-Eval` correctly by @bts in [#9456](#9456) - **(http)** improve HTML detection by using Content-Type header by @phateffect in [#9407](#9407) - **(task)** install monorepo subdir tools before running deps by @jdx in [#9454](#9454) ### 📦️ Dependency Updates - update astral-tokio-tar advisory by @jdx in [#9449](#9449) - respect -q flag for provider command stream by @JamBalaya56562 in [#9457](#9457) ### New Contributors - @JamBalaya56562 made their first contribution in [#9457](#9457) - @bts made their first contribution in [#9456](#9456) - @phateffect made their first contribution in [#9407](#9407) --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Summary
Fixes #9445: in a monorepo, running a task from the root via
mise //sub:tasknamefailed whensub/mise.tomldeclared both a tool and an auto[deps]provider that used it (e.g.bun = \"latest\"+[deps.bun] auto=true). The deps step ran before the subdirectory's tool was installed, sobun installdied withNo such file or directory.The user-reported workaround was running
mise -C sub/ depsonce so.mise/deps-state.tomlskipped the broken path on subsequent runs.Root cause
In
Run::run(src/cli/run.rs):get_task_listscorrectly loaded subdirectory tasks viaTaskLoadContext.ToolsetBuilder::build(&config)was then called againstconfig.config_filesonly — which contains the root hierarchy when invoked from the monorepo root, notsub/mise.toml.install_missing_versionsran on that incomplete toolset (nobun).resolve_dependspopulatetask.cfwith the subdirectory configs, which were dutifully passed toDepsEngine::add_config_files— too late: install had already finished.engine.run({ auto_only: true })invokedbun install, which couldn't findbun.Fix
Reorder so
resolve_dependsruns before the toolset is built, then collect subdirectory configs from the resolved tasks (task.cf), merge them into aConfigMaptogether withconfig.config_files, and pass the result to the existingToolsetBuilder::with_config_files(...)API. Subdir tools are now installed before any[deps]step runs. The deps engine continues to receive the same subdir configs as before.No new APIs;
with_config_filesalready existed onToolsetBuilder.The "naked run that does not match a task should fail without installing project tools" invariant still holds —
resolve_dependsruns afterget_task_lists, and any failure short-circuits before the toolset is touched.Out of scope
Config::get_toolset()is a separate lazily-cached toolset used by usage-spec parsing; it still reflects only the root hierarchy. Extending it to monorepo subdirs has wider blast radius (env, aliases, everyparse_usage_values_from_taskcall) and is not needed to fix this bug.Test plan
tiny/rtx-tinyminimal repro mirroring the discussion.e2e/tasks/test_task_monorepo_deps_tool_install(uses thetinytool + a[deps]step that invokesrtx-tiny, all from the monorepo root via//sub:use-tiny).mise run test:e2e tasks/test_task_monorepo— all monorepo task tests pass.mise run test:e2e cli/test_deps cli/test_deps_tool_install cli/test_deps_depends tasks/test_task_deps— pass.mise run test:unit— 785/785 pass.mise run lint-fixandcargo clippy --all-targets -- -D warningsclean.🤖 Generated with Claude Code
Note
Medium Risk
Changes
mise runexecution ordering and toolset construction, which can affect tool installation and dependency steps across projects (especially monorepos). Scope is localized to therunpath but touches core task/deps orchestration.Overview
Fixes
mise run //sub:taskin monorepos by resolving task dependencies before building/installing the toolset, then merging resolved tasks’ subdirectory config files into the toolset’s config map so subdir-declared tools are onPATHbefore auto[deps]steps execute.Adds an e2e regression test that sets up a monorepo root +
sub/mise.tomlwith a subdir tool (tiny) and an auto[deps]step that uses it, asserting the tool is installed and both deps and task execution succeed from the repo root.Reviewed by Cursor Bugbot for commit ad6aec9. Bugbot is set up for automated code reviews on this repo. Configure here.