denoland/deno · error · anyhow::Error

Task not found: {}

Error message

Task not found: {}

What it means

`deno task` resolves the task graph by walking each matched task and its declared dependencies topologically (`sort_tasks_topo`). If a visited name — the requested task or any name listed in a task's `dependencies` — is not defined in the member's or root's task config, `TaskError::NotFound` surfaces here. Under `deno task --run` it is a returned error; otherwise it is logged, available tasks are printed, and the run exits 1.

Source

Thrown at cli/tools/task.rs:434

impl<'a> TaskRunner<'a> {
  /// Topologically sort all matched tasks across the given packages into a
  /// single flat list, then run them through `run_tasks_in_parallel` so tasks
  /// from sibling packages execute concurrently.
  pub async fn run_all_tasks(
    &self,
    packages: &'a [PackageTaskInfo],
    task_name: &str,
    kill_signal: &KillSignal,
    argv: &'a [String],
  ) -> Result<i32, deno_core::anyhow::Error> {
    let mut sorted: Vec<ResolvedTask<'a>> = Vec::new();
    for pkg in packages {
      if let Err(err) = sort_tasks_topo(pkg, &mut sorted) {
        return match err {
          TaskError::NotFound(name) => {
            if self.task_flags.is_run {
              return Err(anyhow!("Task not found: {}", name));
            }
            log::error!("Task not found: {}", name);
            if log::log_enabled!(log::Level::Error) {
              self.print_available_tasks(&pkg.tasks_config)?;
            }
            Ok(1)
          }
          TaskError::TaskDepCycle { path } => {
            log::error!("Task cycle detected: {}", path.join(" -> "));
            Ok(1)
          }
        };
      }
    }

    if sorted.is_empty() {
      if self.task_flags.is_run {
        return Err(anyhow!("Task not found: {}", task_name));

View on GitHub (pinned to 89f33cbef2)

Solutions

  1. Run `deno task` with no arguments to list the defined task names
  2. Fix the typo or add the missing task definition under `"tasks"` in deno.json (member or workspace root)
  3. Remember lookup order: the member config first, then the root config — the dependency must exist in one of them
  4. Avoid `deno task --run` for optional tasks; it turns NotFound into a hard error

Example fix

// before — deno.json
{
  "tasks": {
    "dev": { "dependencies": ["serve"] }
  }
}
// 'serve' is not defined
// after
{
  "tasks": {
    "dev": { "dependencies": ["server"] },
    "server": "deno run --watch server.ts"
  }
}
Defensive patterns

Strategy: validation

Validate before calling

# fail fast if any task dependency is undefined (deno.json)
deno eval 'const t = JSON.parse(Deno.readTextFileSync("deno.json").replace(/^\/\/.*$/gm, "")).tasks ?? {};
const known = new Set(Object.keys(t));
for (const [name, def] of Object.entries(t)) {
  for (const d of def.dependencies ?? []) {
    if (!known.has(d)) { console.error(`task ${name} -> undefined dependency ${d}`); Deno.exit(1); }
  }
}'

Prevention

When it happens

Trigger: A task's `dependencies` array references an undefined task name (typo, renamed task, task defined only in a different member), or a matched task name does not exist in the member or root config being walked.

Common situations: Refactoring deno.json task names without updating dependents; workspace members expecting root tasks that were moved; typos in dependency lists.

Related errors


AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16). Data as JSON: /api/errors/5ab5a4a4b115a93b. Report an issue: GitHub.