fix(task): resolve project tasks in run blocks using TaskLoadContext#6614
fix(task): resolve project tasks in run blocks using TaskLoadContext#6614
Conversation
When a task's run block referenced project tasks (e.g., `{ task = "//projects/backend:hello" }`),
those tasks were not being loaded properly, causing "task not found" errors.
The root cause was that `inject_and_wait` was calling `config.tasks_with_aliases()`, which uses
a default `TaskLoadContext` with `load_all: false` and empty `path_hints`. This context won't
load tasks from project subdirectories in monorepo mode.
The fix creates a proper `TaskLoadContext` from the task specs being injected, ensuring that
all necessary project tasks are loaded before attempting to resolve and execute them.
Fixes: #6615
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Pull Request Overview
This PR fixes a bug where project tasks referenced in root task run blocks were not being loaded properly in monorepo configurations, causing "task not found" errors.
- Replaces
config.tasks_with_aliases()withconfig.tasks_with_context()using a proper TaskLoadContext - Creates TaskLoadContext from task specs to include project directory path hints
- Manually rebuilds the tasks map with aliases to maintain existing functionality
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/cli/run.rs | Updates inject_and_wait function to use TaskLoadContext for proper project task loading |
| e2e/tasks/test_task_monorepo_run_project_tasks | Adds comprehensive e2e test covering single and multiple project task scenarios |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| let ctx = TaskLoadContext::from_patterns(specs.iter().map(|s| { | ||
| let (name, _) = split_task_spec(s); | ||
| name | ||
| })); |
There was a problem hiding this comment.
[nitpick] The anonymous closure is simple enough to be written inline without the intermediate variable assignment. Consider: TaskLoadContext::from_patterns(specs.iter().map(|s| split_task_spec(s).0))
| let ctx = TaskLoadContext::from_patterns(specs.iter().map(|s| { | |
| let (name, _) = split_task_spec(s); | |
| name | |
| })); | |
| let ctx = TaskLoadContext::from_patterns(specs.iter().map(|s| split_task_spec(s).0)); |
| .iter() | ||
| .map(|a| (a.to_string(), t.clone())) | ||
| .chain(once((t.name.clone(), t.clone()))) | ||
| .collect::<Vec<_>>() |
There was a problem hiding this comment.
The intermediate collect::<Vec<_>>() on line 1241 is unnecessary and creates an extra allocation. Remove it to allow the iterator chain to be processed directly by the final collect().
| .collect::<Vec<_>>() |
There was a problem hiding this comment.
Bug: Owned Task Iteration Dereferencing Error
The tasks_map now holds owned Task values, making t an owned Task in the iteration. Attempting to dereference t with (*t).clone() is incorrect for an owned value, leading to a compilation error.
src/cli/run.rs#L1249-L1250
Lines 1249 to 1250 in 4f8ad02
Hyperfine Performance
|
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2025.10.6 x -- echo |
17.9 ± 0.2 | 17.5 | 20.3 | 1.00 |
mise x -- echo |
18.0 ± 0.3 | 17.6 | 22.1 | 1.01 ± 0.02 |
mise env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2025.10.6 env |
17.4 ± 0.2 | 16.9 | 19.1 | 1.00 |
mise env |
17.6 ± 0.6 | 17.0 | 23.0 | 1.01 ± 0.04 |
mise hook-env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2025.10.6 hook-env |
17.1 ± 0.3 | 16.7 | 21.2 | 1.00 |
mise hook-env |
17.1 ± 0.2 | 16.8 | 17.9 | 1.00 ± 0.02 |
mise ls
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2025.10.6 ls |
14.9 ± 0.4 | 14.5 | 20.3 | 1.00 |
mise ls |
15.0 ± 0.2 | 14.6 | 15.7 | 1.01 ± 0.03 |
xtasks/test/perf
| Command | mise-2025.10.6 | mise | Variance |
|---|---|---|---|
| install (cached) | 197ms | ✅ 104ms | +89% |
| ls (cached) | 62ms | 63ms | -1% |
| bin-paths (cached) | 69ms | 68ms | +1% |
| task-ls (cached) | 468ms | 466ms | +0% |
✅ Performance improvement: install cached is 89%
### 📦 Registry - add lazyssh by @TyceHerrman in [#6610](#6610) ### 🚀 Features - **(config)** Add a ceiling to how mise searchs for config & tasks by @richardthe3rd in [#6041](#6041) ### 🐛 Bug Fixes - **(task)** use config_root instead of project_root for task base path by @risu729 in [#6609](#6609) - **(task)** resolve project tasks in run blocks using TaskLoadContext by @jdx in [#6614](#6614) - **(task)** dont truncate task message when CI is set by @roele in [#6620](#6620) - **(ui)** prevent OSC 9;4 progress sequences from being written to non-terminals by @jdx in [#6615](#6615) ### Chore - remove cosign/slsa-verifier from mise.toml by @jdx in [#6616](#6616) ### New Contributors - @richardthe3rd made their first contribution in [#6041](#6041)
Summary
Problem
When a task's run block referenced project tasks (e.g.,
{ task = "//projects/backend:hello" }),those tasks were not being loaded properly, causing "task not found" errors. This occurred even
though the same tasks worked correctly when referenced via
depends.Root Cause
The
inject_and_waitfunction was callingconfig.tasks_with_aliases(), which uses a defaultTaskLoadContextwithload_all: falseand emptypath_hints. This context won't load tasksfrom project subdirectories in monorepo mode.
Solution
Modified
inject_and_waitto:TaskLoadContextfrom the task specs being injectedconfig.tasks_with_context(Some(&ctx))instead ofconfig.tasks_with_aliases()tasks_with_aliases())This ensures that when a task references project tasks in its run block, those project
directories are included in the TaskLoadContext path hints, causing their tasks to be loaded.
Test plan
test_task_monorepo_run_project_taskspassestest_task_monorepo_dependencies,test_task_run_depends)Fixes: #6615
🤖 Generated with Claude Code
Note
Ensure project tasks referenced in run blocks are resolved using TaskLoadContext; add e2e coverage for monorepo task invocation.
inject_and_waitinsrc/cli/run.rsto construct aTaskLoadContextfrom run-block specs and useconfig.tasks_with_context(...), then rebuild alias map to resolve tasks (including monorepo project tasks).TaskLoadContextto support context-aware task loading.e2e/tasks/test_task_monorepo_run_project_tasksvalidating://projects/backend:hello.Written by Cursor Bugbot for commit 4f8ad02. This will update automatically on new commits. Configure here.