Skip to content

fix(task): fetch remote task files before parsing usage specs#8979

Merged
jdx merged 3 commits intomainfrom
fix/remote-task-usage-warning
Apr 9, 2026
Merged

fix(task): fetch remote task files before parsing usage specs#8979
jdx merged 3 commits intomainfrom
fix/remote-task-usage-warning

Conversation

@jdx
Copy link
Copy Markdown
Owner

@jdx jdx commented Apr 9, 2026

Summary

  • Fixes spurious failed to parse task file warning when running remote git tasks with arguments
  • Remote task files were not fetched before parse_usage_values_from_task attempted to read them (introduced when the {{usage.*}} dependency template feature was added)
  • Fetches remote files early in run.rs (before usage spec parsing) and in deps.rs (for dependency tasks resolved from config)

Closes #8973

Test plan

  • New e2e test test_task_remote_dep_no_warning verifies no warning when running remote tasks with args
  • Test fails on main and passes with fix
  • Existing tests pass: test_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 usage warnings when running remote file-based tasks with extra args by ensuring remote task files are fetched to a local cache before parse_usage_values_from_task attempts to read usage specs.

mise run now 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.

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-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 9, 2026

Greptile Summary

This PR fixes a spurious failed to parse task file warning triggered when running remote git-based file tasks with arguments. The root cause was that parse_usage_values_from_task attempted to read task files before remote files were fetched to a local cache path. The fix introduces two new fetch points: one in run.rs immediately after the task list is built (before usage-spec parsing), and one inside the Deps::new stack loop in deps.rs (for remote tasks discovered during dependency graph construction). Task deduplication is unaffected since Task::PartialEq is keyed on name/args/env — not the file path — so already-fetched tasks are correctly recognized as equal in the seen set. A regression e2e test is added that spins up a local git HTTP server and asserts no parse-warning appears when a remote task is invoked with extra args.

Confidence Score: 5/5

Safe 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.

Vulnerabilities

No security concerns identified. Remote task file fetching was already present before this PR; the change only adjusts the ordering of fetch vs. parse. The is_remote_source guard correctly limits the new early-fetch path to git/http/https URLs.

Important Files Changed

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
Loading

Reviews (3): Last reviewed commit: "refactor(task): reuse TaskFetcher::is_re..." | Re-trigger Greptile

Comment thread src/task/deps.rs Outdated
Comment thread src/task/deps.rs Outdated
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 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.

Comment thread src/task/deps.rs Outdated
add_idx(t, &mut graph);
}
let all_tasks_to_run = resolve_depends(config, tasks).await?;
let fetcher = TaskFetcher::new(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

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.

Comment thread src/task/deps.rs
Comment on lines +78 to +82
{
let mut tasks_to_fetch = vec![a];
fetcher.fetch_tasks(&mut tasks_to_fetch).await?;
a = tasks_to_fetch.into_iter().next().unwrap();
}
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

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>
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ 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.

Comment thread src/task/deps.rs Outdated
…ng check

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jdx jdx enabled auto-merge (squash) April 9, 2026 16:30
@jdx jdx merged commit f3807b1 into main Apr 9, 2026
36 checks passed
@jdx jdx deleted the fix/remote-task-usage-warning branch April 9, 2026 16:32
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 9, 2026

Hyperfine Performance

mise x -- echo

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%

mise-en-dev added a commit that referenced this pull request Apr 10, 2026
### 🚀 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)
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