Skip to content

fix(task): show available tasks when run target missing#9141

Merged
jdx merged 2 commits intomainfrom
codex/task-missing-suggestions
Apr 16, 2026
Merged

fix(task): show available tasks when run target missing#9141
jdx merged 2 commits intomainfrom
codex/task-missing-suggestions

Conversation

@jdx
Copy link
Copy Markdown
Owner

@jdx jdx commented Apr 16, 2026

Summary

  • show similar task suggestions for missing mise run <task> targets using the resolved task set
  • append a compact available-task table to missing-task errors
  • load the tasks ls --all task view for monorepo missing-task errors so sibling package tasks are visible

Validation

  • mise run format
  • mise run test:e2e e2e/tasks/test_task_missing_suggestions

Note

Low Risk
Changes are limited to the missing-task error path and an added e2e test; primary risk is minor UX/performance impact from loading monorepo-wide tasks when a task is missing.

Overview
Improves the mise run <task> missing-target error to suggest similar task names and append a compact Available tasks table (name + first-line description, capped at 20 with a hint to list all).

For monorepo contexts (or // task paths), the error now loads the tasks ls --all view so suggestions and the available-task list include sibling package tasks, and adds an e2e test covering both single-project and monorepo missing-task output.

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

@jdx jdx marked this pull request as ready for review April 16, 2026 12:47
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 improves the error messages when a task is not found by providing similar task suggestions and a list of available tasks, including specific enhancements for monorepo environments. A new end-to-end test ensures these suggestions are correctly displayed. The review feedback suggests optimizing the task retrieval logic to avoid redundant asynchronous calls when operating within a monorepo.

Comment thread src/task/task_list.rs
Comment on lines +107 to +125
async fn tasks_for_missing_task_error(
config: &Config,
name: &str,
) -> Result<(Arc<BTreeMap<String, Task>>, bool)> {
let tasks = config.tasks().await?;

// In monorepos, users usually need `tasks ls --all` after a miss. Load that
// same view for the error so sibling package tasks can be suggested.
if (name.starts_with("//") || config.is_monorepo())
&& let Ok(all_tasks) = config
.tasks_with_context(Some(&TaskLoadContext::all()))
.await
&& !all_tasks.is_empty()
{
return Ok((all_tasks, true));
}

Ok((tasks, false))
}
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

This function can be made more efficient by avoiding the unconditional call to config.tasks().await?. This call is redundant when in a monorepo context and all tasks are loaded. By restructuring the function, we can load tasks only when necessary, improving performance in monorepo scenarios and improving readability.

Suggested change
async fn tasks_for_missing_task_error(
config: &Config,
name: &str,
) -> Result<(Arc<BTreeMap<String, Task>>, bool)> {
let tasks = config.tasks().await?;
// In monorepos, users usually need `tasks ls --all` after a miss. Load that
// same view for the error so sibling package tasks can be suggested.
if (name.starts_with("//") || config.is_monorepo())
&& let Ok(all_tasks) = config
.tasks_with_context(Some(&TaskLoadContext::all()))
.await
&& !all_tasks.is_empty()
{
return Ok((all_tasks, true));
}
Ok((tasks, false))
}
async fn tasks_for_missing_task_error(
config: &Config,
name: &str,
) -> Result<(Arc<BTreeMap<String, Task>>, bool)> {
// In monorepos, users usually need tasks ls --all after a miss. Load that
// same view for the error so sibling package tasks can be suggested.
if name.starts_with("//") || config.is_monorepo() {
if let Ok(all_tasks) = config
.tasks_with_context(Some(&TaskLoadContext::all()))
.await
{
if !all_tasks.is_empty() {
return Ok((all_tasks, true));
}
}
}
let tasks = config.tasks().await?;
Ok((tasks, false))
}

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 16, 2026

Greptile Summary

This PR improves the error experience when mise run <task> can't find the requested task. The key changes are: (1) a new tasks_for_missing_task_error helper that loads the monorepo-wide task view when the request is monorepo-shaped or a monorepo root is configured, (2) a unified similar_tasks function replacing the old monorepo-only fuzzy-match logic, and (3) append_available_tasks that appends a compact name+description table (capped at 20 entries) to every missing-task error. A new e2e test covers both single-project and monorepo scenarios.

Confidence Score: 5/5

Safe to merge — all changes are on the error path and cannot affect successful task execution.

No P0 or P1 findings. The logic is correct: tasks are loaded at most once per error path, the monorepo branch silently swallows its own errors before falling back, and the available-tasks table is capped. The new e2e test covers the key scenarios. All remaining observations are P2 or lower.

No files require special attention.

Important Files Changed

Filename Overview
src/task/task_list.rs Adds three helper functions (tasks_for_missing_task_error, similar_tasks, append_available_tasks) and refactors err_no_task to produce richer error output; logic is sound and tasks are loaded at most once per error path.
e2e/tasks/test_task_missing_suggestions New e2e test covering typo suggestions, available-task listing, and monorepo missing-task errors; the mid-test rm serves as a scenario reset, not an end-of-test cleanup, which is fine.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["mise run &lt;task&gt;"] --> B["get_task_lists()"]
    B --> C{"Task found?"}
    C -- Yes --> D["Execute task"]
    C -- No --> E["err_no_task(config, name)"]
    E --> F["suggest_similar_commands(name)"]
    E --> G["tasks_for_missing_task_error(config, name)"]
    G --> H{"name starts with // OR config.is_monorepo()?"}
    H -- Yes --> I["tasks_with_context(all)"]
    I --> J{"non-empty?"}
    J -- Yes --> K["return (all_tasks, showing_all=true)"]
    J -- No --> L["config.tasks()"]
    H -- No --> L
    L --> M["return (tasks, showing_all=false)"]
    K --> N{"tasks_for_error empty?"}
    M --> N
    N -- Yes --> O["bail: no tasks defined / untrusted config / non-exec files"]
    N -- No --> P["similar_tasks(name, tasks_for_error)"]
    P --> Q{"similar found?"}
    Q -- Yes --> R["append 'Did you mean one of these?'"]
    Q -- No --> S["skip suggestions"]
    R --> T["append_available_tasks(err_msg, tasks_for_error, showing_all)"]
    S --> T
    T --> U["bail with formatted error message"]
Loading

Fix All in Claude Code

Reviews (2): Last reviewed commit: "fix(task): avoid redundant missing-task ..." | Re-trigger Greptile

@jdx jdx force-pushed the codex/task-missing-suggestions branch from a88fbd2 to ebd880f Compare April 16, 2026 12:54
@jdx jdx enabled auto-merge (squash) April 16, 2026 13:06
@jdx jdx merged commit 0a4bb64 into main Apr 16, 2026
36 checks passed
@jdx jdx deleted the codex/task-missing-suggestions branch April 16, 2026 13:11
@github-actions
Copy link
Copy Markdown

Hyperfine Performance

mise x -- echo

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.4.14 x -- echo 22.8 ± 0.6 21.5 24.9 1.00
mise x -- echo 23.6 ± 0.7 22.0 30.5 1.04 ± 0.04

mise env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.4.14 env 22.5 ± 0.8 21.2 27.8 1.00
mise env 22.9 ± 0.8 21.5 26.5 1.02 ± 0.05

mise hook-env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.4.14 hook-env 23.4 ± 0.7 21.9 26.7 1.00
mise hook-env 23.9 ± 0.8 22.3 26.8 1.02 ± 0.05

mise ls

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.4.14 ls 20.4 ± 0.6 19.1 22.4 1.00
mise ls 21.4 ± 0.8 19.6 23.8 1.05 ± 0.05

xtasks/test/perf

Command mise-2026.4.14 mise Variance
install (cached) 150ms 150ms +0%
ls (cached) 79ms 81ms -2%
bin-paths (cached) 86ms 86ms +0%
task-ls (cached) 832ms 808ms +2%

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

- **(registry)** add .perl-version support for perl by @ergofriend in
[#9102](#9102)
- **(task)** add Tera template support for inline table run tasks by
@iamkroot in [#9079](#9079)

### 🐛 Bug Fixes

- **(env)** use runtime symlink paths for fuzzy versions by @jdx in
[#9143](#9143)
- **(github)** use full token resolution chain for attestation
verification by @jdx in [#9154](#9154)
- **(go)** Remove install-time version override for subpath packages by
@c22 in [#9135](#9135)
- **(npm)** respect install_before when resolving dist-tag versions by
@webkaz in [#9145](#9145)
- **(self-update)** ensure subcommand exists by @salim-b in
[#9144](#9144)
- **(task)** show available tasks when run target missing by @jdx in
[#9141](#9141)
- **(task)** forward task help args and add raw_args by @jdx in
[#9118](#9118)
- **(task)** remove red/yellow from task prefix colors by
@lechuckcaptain in [#8782](#8782)
- **(task)** merge TOML task block into same-named file task and surface
resolved dir by @jdx in [#9147](#9147)
- **(toolset)** round-trip serialized tool options by @atharvasingh7007
in [#9124](#9124)
- **(vfox)** fallback to absolute bin path if env_keys not set by
@80avin in [#9151](#9151)

### 📚 Documentation

- make agent guide wording generic by @jdx in
[#9142](#9142)

### 📦️ Dependency Updates

- update ghcr.io/jdx/mise:deb docker digest to e019cb9 by @renovate[bot]
in [#9160](#9160)
- update ghcr.io/jdx/mise:copr docker digest to 8d25608 by
@renovate[bot] in [#9159](#9159)
- update ghcr.io/jdx/mise:rpm docker digest to 22e52da by @renovate[bot]
in [#9161](#9161)
- update ghcr.io/jdx/mise:alpine docker digest to a3da97c by
@renovate[bot] in [#9158](#9158)
- update rust docker digest to 4a2ef38 by @renovate[bot] in
[#9162](#9162)
- update ubuntu:24.04 docker digest to c4a8d55 by @renovate[bot] in
[#9164](#9164)
- update rust crate aws-lc-rs to v1.16.3 by @renovate[bot] in
[#9165](#9165)
- update ubuntu docker tag to resolute-20260413 by @renovate[bot] in
[#9169](#9169)
- update rust crate clap to v4.6.1 by @renovate[bot] in
[#9166](#9166)
- update taiki-e/install-action digest to a2352fc by @renovate[bot] in
[#9163](#9163)
- update rust crate ctor to 0.10 by @renovate[bot] in
[#9170](#9170)
- update rust crate tokio to v1.52.1 by @renovate[bot] in
[#9167](#9167)
- update rust crate rmcp-macros to 0.17 by @renovate[bot] in
[#9173](#9173)
- update rust crate signal-hook to 0.4 by @renovate[bot] in
[#9177](#9177)
- update rust crate zipsign-api to 0.2 by @renovate[bot] in
[#9180](#9180)
- update rust crate toml_edit to 0.25 by @renovate[bot] in
[#9179](#9179)
- update rust crate strum to 0.28 by @renovate[bot] in
[#9178](#9178)

### 📦 Registry

- add ibmcloud by @dnwe in
[#9139](#9139)
- add rush by @jdx in [#9146](#9146)

### New Contributors

- @80avin made their first contribution in
[#9151](#9151)
- @atharvasingh7007 made their first contribution in
[#9124](#9124)
- @lechuckcaptain made their first contribution in
[#8782](#8782)
- @ergofriend made their first contribution in
[#9102](#9102)
- @dnwe made their first contribution in
[#9139](#9139)

## 📦 Aqua Registry Updates

#### New Packages (3)

-
[`controlplaneio-fluxcd/flux-operator`](https://github.com/controlplaneio-fluxcd/flux-operator)
-
[`dependency-check/DependencyCheck`](https://github.com/dependency-check/DependencyCheck)
- [`kiro.dev/kiro-cli`](https://github.com/kiro.dev/kiro-cli)

#### Updated Packages (2)

-
[`jreleaser/jreleaser/standalone`](https://github.com/jreleaser/jreleaser/standalone)
- [`sigstore/cosign`](https://github.com/sigstore/cosign)
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