Skip to content

fix(task): skip tool install for missing naked tasks#9374

Merged
jdx merged 1 commit intomainfrom
codex/naked-run-no-install
Apr 24, 2026
Merged

fix(task): skip tool install for missing naked tasks#9374
jdx merged 1 commit intomainfrom
codex/naked-run-no-install

Conversation

@jdx
Copy link
Copy Markdown
Owner

@jdx jdx commented Apr 24, 2026

Summary

  • resolve task names before installing project tools in mise run
  • prevents naked runs with no matching task from auto-installing configured tools before failing
  • add an e2e regression that proves a missing naked task does not install dummy

Test

  • cargo fmt --all -- --check
  • cargo check --all-features
  • mise run test:e2e e2e/cli/test_naked_run_no_install
  • commit hook checks

Note

Low Risk
Low risk reorder of initialization logic in mise run, mainly affecting error paths when no matching task exists; normal task execution still installs tools as before.

Overview
mise run now resolves the requested task list (and initializes temp/run state) before building/installing the project toolset, so invoking a non-existent task fails without auto-installing configured tools.

Adds an e2e regression test (e2e/cli/test_naked_run_no_install) that asserts a missing task reports "no tasks defined" and does not create an install directory for a configured dummy tool.

Reviewed by Cursor Bugbot for commit 9551c4f. Bugbot is set up for automated code reviews on this repo. Configure here.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request modifies the task execution flow in src/cli/run.rs to resolve tasks before installing tools, ensuring that invalid task calls do not trigger unnecessary tool installations. A new E2E test was added to verify this behavior. However, the reviewer noted that this change might prevent the discovery of tasks provided by plugins that are not yet installed. Additionally, moving the time!("run init") marker causes it to include tool installation time, which may negatively impact telemetry accuracy.

Comment thread src/cli/run.rs
.chain(self.args.clone())
.collect_vec();

let mut task_list = get_task_lists(&config, &args, true, self.skip_deps).await?;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Moving task resolution before tool installation may break the ability to run tasks provided by plugins that are not yet installed. In mise, some tasks are discovered from installed plugins. If a user attempts to run such a task, get_task_lists will now fail early because the plugin (and its tasks) are not yet available on the filesystem. Previously, mise would install the tools first, making the plugin tasks discoverable before resolution. Consider if this regression is acceptable or if get_task_lists should be made aware of potential tasks from tools slated for installation.

Comment thread src/cli/run.rs
self.skip_deps = Settings::get().task.skip_depends;
}

time!("run init");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The time!("run init") marker now includes the duration of tool installation (install_missing_versions) because it was moved from line 317 to line 298, while the tool installation logic was moved into the block following it. This will significantly change the meaning of the "run init" metric in telemetry, as tool installation can be a slow operation. Additionally, the time!("run get_task_lists") marker (at line 362, though not shown in this diff) is now misplaced as it occurs after the tasks have already been resolved.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 24, 2026

Greptile Summary

This PR fixes a regression where mise run <missing-task> would trigger auto-installation of configured project tools before failing with "no task found." The fix reorders operations in Run::run() so that get_task_lists is called (and can return early with an error) before ToolsetBuilder builds and installs the toolset. A new e2e regression test validates the behavior end-to-end.

Confidence Score: 5/5

Safe to merge — the fix is a clean reordering with no functional regressions for valid task runs.

The change is a minimal, well-motivated reordering: task resolution now happens before toolset installation, short-circuiting on error. Valid task paths are unaffected because both steps still occur, just in the new order. A targeted e2e regression test proves the fix. No security concerns.

No files require special attention.

Important Files Changed

Filename Overview
src/cli/run.rs Reorders task-resolution before toolset installation so a missing task errors out before tools are installed; the relative order of all other operations is preserved.
e2e/cli/test_naked_run_no_install New e2e regression test: creates a mise.toml with a dummy tool, runs a non-existent task, and asserts both the expected failure message and that the dummy tool was not installed.

Sequence Diagram

sequenceDiagram
    participant User
    participant RunCmd as Run::run()
    participant TaskList as get_task_lists()
    participant Toolset as ToolsetBuilder / install_missing_versions()

    Note over RunCmd: Before fix
    RunCmd->>Toolset: build & install tools (dummy installed!)
    RunCmd->>TaskList: resolve task list
    TaskList-->>RunCmd: Error: no task found
    RunCmd-->>User: Error (but tool already installed)

    Note over RunCmd: After fix (this PR)
    RunCmd->>TaskList: resolve task list
    TaskList-->>RunCmd: Error: no task found
    RunCmd-->>User: Error (tool install never reached)

    Note over RunCmd: Happy path (unchanged)
    RunCmd->>TaskList: resolve task list
    TaskList-->>RunCmd: task_list resolved
    RunCmd->>Toolset: build & install tools
    Toolset-->>RunCmd: toolset ready
    RunCmd-->>User: task executed
Loading

Reviews (1): Last reviewed commit: "fix(task): skip tool install for missing..." | Re-trigger Greptile

@jdx jdx enabled auto-merge (squash) April 24, 2026 20:14
@jdx jdx merged commit 0df44be into main Apr 24, 2026
38 checks passed
@jdx jdx deleted the codex/naked-run-no-install branch April 24, 2026 20:30
@github-actions
Copy link
Copy Markdown

Hyperfine Performance

mise x -- echo

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.4.20 x -- echo 19.4 ± 0.6 18.3 30.1 1.00
mise x -- echo 20.3 ± 0.3 19.6 21.6 1.05 ± 0.04

mise env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.4.20 env 18.8 ± 0.3 18.2 20.0 1.00
mise env 19.8 ± 0.4 19.0 21.5 1.06 ± 0.03

mise hook-env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.4.20 hook-env 19.8 ± 0.6 18.7 27.6 1.00
mise hook-env 20.5 ± 0.4 19.6 22.6 1.04 ± 0.04

mise ls

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.4.20 ls 17.5 ± 1.2 16.3 33.3 1.00
mise ls 18.1 ± 0.6 17.3 20.2 1.04 ± 0.08

xtasks/test/perf

Command mise-2026.4.20 mise Variance
install (cached) 132ms 137ms -3%
ls (cached) 63ms 66ms -4%
bin-paths (cached) 66ms 68ms -2%
task-ls (cached) 637ms 627ms +1%

mise-en-dev added a commit that referenced this pull request Apr 25, 2026
### 🚀 Features

- **(registry)** add --security flag to include security info in JSON
output by @jdx in [#9364](#9364)

### 🐛 Bug Fixes

- **(config)** limit resolved backend opts to aliases by @risu729 in
[#9315](#9315)
- **(docs)** stack banner message and link on mobile by @jdx in
[#9362](#9362)
- **(github)** prefer shortest asset name as tiebreaker in
auto-detection by @jdx in [#9361](#9361)
- **(java)** newer zulu versions use a different directory structure by
@roele in [#9365](#9365)
- **(prune)** respect tracked lockfiles by @jdx in
[#9373](#9373)
- **(task)** skip tool install for missing naked tasks by @jdx in
[#9374](#9374)
- **(trust)** add untrust command by @jdx in
[#9370](#9370)
- fix - flux-operator-mcp aqua path by @monotek in
[#9357](#9357)

### 📚 Documentation

- update ruby compile msg by @fladson in
[#9338](#9338)

### 📦️ Dependency Updates

- update ubuntu docker tag to v26 by @renovate[bot] in
[#9347](#9347)
- update ghcr.io/jdx/mise:deb docker digest to 1af5a69 by @renovate[bot]
in [#9352](#9352)
- update taiki-e/install-action digest to 787505c by @renovate[bot] in
[#9354](#9354)
- update ghcr.io/jdx/mise:rpm docker digest to 7015ff3 by @renovate[bot]
in [#9353](#9353)
- update ghcr.io/jdx/mise:copr docker digest to da63a0f by
@renovate[bot] in [#9351](#9351)
- update ghcr.io/jdx/mise:alpine docker digest to 461700f by
@renovate[bot] in [#9350](#9350)
- bump communique 1.0.3 → 1.0.4 by @jdx in
[#9378](#9378)

### 📦 Registry

- remove openshift-install by @jdx in
[#9372](#9372)
- remove go-sdk by @jdx in
[#9371](#9371)

### Chore

- **(npm-publish)** use aube publish instead of npm publish by @jdx in
[#9328](#9328)

### New Contributors

- @fladson made their first contribution in
[#9338](#9338)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant