fix(task): fetch remote task files before parsing usage specs#8979
Conversation
Remote git task files were not fetched before `parse_usage_values_from_task`
attempted to read them, causing a spurious "failed to parse task file" warning
when running remote tasks with arguments. This was introduced when the
`{{usage.*}}` dependency template feature was added.
Fix by fetching remote task files in two places:
- In `run.rs`: fetch before the usage spec parsing loop
- In `deps.rs`: fetch each task as it's processed in the dependency graph,
ensuring dependency tasks from config also have their files resolved
Closes #8973
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Greptile SummaryThis PR fixes a spurious Confidence Score: 5/5Safe to merge — the fix is well-scoped, fetch calls are idempotent for already-local tasks, and Task equality (keyed on name/args/env, not file path) ensures the seen-set in Deps::new deduplicates correctly. All findings are P2 or lower. The three-level fetch strategy (pre-usage-parse, pre-Deps::new, inside Deps::new traversal) is correct and harmless. The no_cache flag is now read from settings in deps.rs, addressing the prior review concern. Task PartialEq/Hash do not include the file field, so remote-to-local path conversion does not break deduplication. The regression test is well-targeted. No files require special attention.
|
| Filename | Overview |
|---|---|
| src/cli/run.rs | Adds an early fetch_tasks call on task_list before usage-spec parsing; fetch in prepare_tasks is retained to cover transitive deps added by resolve_depends. Both fetches are harmless for already-resolved local-path tasks. |
| src/task/deps.rs | Adds per-task remote fetch inside the stack loop before usage-spec rendering; uses Settings::get().task.remote_no_cache so the --no-cache flag (via env var) is respected for transitively discovered tasks. |
| src/task/task_fetcher.rs | Adds is_remote_source as a public helper so callers can check remote-ness without duplicating the git::/http(s):// prefix logic; otherwise unchanged. |
| e2e/tasks/test_task_remote_dep_no_warning | New regression test that spins up a local git HTTP server and verifies no 'failed to parse task file' warning is emitted when running a remote task with extra args; coupled to a specific remote ref path. |
Sequence Diagram
sequenceDiagram
participant run as run.rs (Run::run)
participant fetcher as TaskFetcher
participant deps as Deps::new
participant parser as parse_usage_values_from_task
run->>fetcher: fetch_tasks(task_list) [1st fetch: before usage parsing]
fetcher-->>run: remote URLs → local cache paths
run->>parser: parse_usage_values_from_task(task)
parser-->>run: usage values (file now local, no warning)
run->>run: resolve_depends(task_list) → resolved_tasks
run->>run: prepare_tasks(resolved_tasks)
run->>fetcher: fetch_tasks(resolved_tasks) [2nd fetch: transitive deps]
fetcher-->>run: any new remote deps resolved
run->>deps: Deps::new(config, resolved_tasks)
loop for each task on stack
deps->>fetcher: fetch_tasks([task]) [3rd fetch: graph-traversal deps]
fetcher-->>deps: local path (cached if already fetched)
deps->>parser: parse_usage_values_from_task (if task has args + usage deps)
parser-->>deps: usage values resolved correctly
end
Reviews (3): Last reviewed commit: "refactor(task): reuse TaskFetcher::is_re..." | Re-trigger Greptile
There was a problem hiding this comment.
Code Review
This pull request ensures that remote task files are fetched before their usage specifications are parsed, resolving an issue where remote tasks with arguments would trigger spurious parsing warnings. This is implemented by integrating TaskFetcher into the Run command and the dependency resolution logic in Deps. An E2E test has been added to verify the fix. Feedback suggests that the no_cache flag in Deps should respect CLI overrides instead of being hardcoded to false. Additionally, the efficiency of fetching tasks within the dependency resolution loop could be improved by batching or pre-filtering for remote tasks.
| add_idx(t, &mut graph); | ||
| } | ||
| let all_tasks_to_run = resolve_depends(config, tasks).await?; | ||
| let fetcher = TaskFetcher::new(false); |
There was a problem hiding this comment.
The no_cache flag is hardcoded to false here. This means that transitive remote dependencies discovered during graph building will not respect the --no-cache CLI flag if it was provided to mise run. While TaskFetcher internally respects the global task.remote_no_cache setting, it won't be aware of the temporary CLI override. Consider propagating the no_cache preference from the Run command through the Deps constructor.
| { | ||
| let mut tasks_to_fetch = vec![a]; | ||
| fetcher.fetch_tasks(&mut tasks_to_fetch).await?; | ||
| a = tasks_to_fetch.into_iter().next().unwrap(); | ||
| } |
There was a problem hiding this comment.
Calling fetch_tasks for every task in the loop is slightly inefficient because fetch_tasks creates a new TaskFileProviders instance internally on every call. While functional, it might be better to either fetch the initial stack in batch before the loop or optimize TaskFetcher to reuse providers. Additionally, since most tasks are local, checking if the task is remote before creating the temporary vector and calling fetch_tasks could avoid unnecessary overhead.
Address PR feedback: - Use Settings::get().task.remote_no_cache instead of hardcoded false - Skip fetch_tasks call for local (non-remote) task files Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 86c01d1. Configure here.
…ng check Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Hyperfine Performance
|
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.4.7 x -- echo |
23.5 ± 0.4 | 22.4 | 25.4 | 1.00 |
mise x -- echo |
24.1 ± 0.4 | 23.0 | 25.5 | 1.03 ± 0.02 |
mise env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.4.7 env |
22.7 ± 0.7 | 21.3 | 27.1 | 1.00 |
mise env |
23.1 ± 1.0 | 21.9 | 40.1 | 1.02 ± 0.05 |
mise hook-env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.4.7 hook-env |
23.3 ± 0.5 | 22.0 | 27.2 | 1.00 |
mise hook-env |
23.8 ± 0.5 | 22.6 | 26.2 | 1.02 ± 0.03 |
mise ls
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.4.7 ls |
20.4 ± 0.4 | 19.5 | 22.0 | 1.00 |
mise ls |
21.6 ± 0.6 | 20.0 | 23.2 | 1.06 ± 0.04 |
xtasks/test/perf
| Command | mise-2026.4.7 | mise | Variance |
|---|---|---|---|
| install (cached) | 149ms | 152ms | -1% |
| ls (cached) | 81ms | 80ms | +1% |
| bin-paths (cached) | 85ms | 86ms | -1% |
| task-ls (cached) | 836ms | 824ms | +1% |
### 🚀 Features - **(config)** add lockfile_platforms setting to restrict lockfile platforms by @cameronbrill in [#8966](#8966) - **(sandbox)** support wildcard patterns in allow_env by @jdx in [#8974](#8974) - bump usage-lib v2 → v3 to render examples in task --help by @baby-joel in [#8890](#8890) ### 🐛 Bug Fixes - **(activate)** handle empty __MISE_FLAGS array with set -u on bash 3.2 by @jdx in [#8988](#8988) - **(env)** add trace logging for module hook PATH diagnostics by @jdx in [#8981](#8981) - **(go)** Query module proxy directly for version resolution by @c22 in [#8968](#8968) - **(install)** render tera templates in tool postinstall hooks by @jdx in [#8978](#8978) - **(install)** add missing env vars to tool postinstall hooks by @jdx in [#8977](#8977) - **(task)** prevent hang when skipped task has dependents by @jdx in [#8937](#8937) - **(task)** invalidate dependent task sources when dependency runs by @jdx in [#8975](#8975) - **(task)** prevent deadlock when MISE_JOBS=1 with sub-task references by @jdx in [#8976](#8976) - **(task)** fetch remote task files before parsing usage specs by @jdx in [#8979](#8979) - **(task)** prevent panic when running parallel sub-tasks with replacing output by @jdx in [#8986](#8986) - **(upgrade)** update lockfile and config when upgrading to specific version by @jdx in [#8983](#8983) ### 📚 Documentation - **(node)** remove "recommended for teams" from pin example by @jdx in [b334363](b334363) ### 📦️ Dependency Updates - update ghcr.io/jdx/mise:alpine docker digest to 17a29f2 by @renovate[bot] in [#8995](#8995) - update docker/dockerfile:1 docker digest to 2780b5c by @renovate[bot] in [#8994](#8994) ### New Contributors - @baby-joel made their first contribution in [#8890](#8890) - @cameronbrill made their first contribution in [#8966](#8966) - @c22 made their first contribution in [#8968](#8968)

Summary
failed to parse task filewarning when running remote git tasks with argumentsparse_usage_values_from_taskattempted to read them (introduced when the{{usage.*}}dependency template feature was added)run.rs(before usage spec parsing) and indeps.rs(for dependency tasks resolved from config)Closes #8973
Test plan
test_task_remote_dep_no_warningverifies no warning when running remote tasks with argsmainand passes with fixtest_task_remote_git_https,test_task_dep_args🤖 Generated with Claude Code
Note
Medium Risk
Changes the task-run and dependency-graph build flow to fetch remote task files earlier, which could affect task resolution/caching behavior and ordering for remote tasks and their dependencies.
Overview
Prevents spurious
failed to parse task file ... with usagewarnings when running remote file-based tasks with extra args by ensuring remote task files are fetched to a local cache beforeparse_usage_values_from_taskattempts to read usage specs.mise runnow pre-fetches remote task files right after task list resolution, and dependency graph construction (Deps::new) also fetches remote task files for dependency tasks and updates the graph node with the fetched version. Adds an e2e regression test (test_task_remote_dep_no_warning) that runs a remote git task with--args against a local git HTTP server and asserts no warning is emitted.Reviewed by Cursor Bugbot for commit 682ea94. Bugbot is set up for automated code reviews on this repo. Configure here.