jdx/mise · error

no tasks defined in {}, but found {} non-executable file(s)

Error message

no tasks defined in {}, but found {} non-executable file(s) in {}.
Files must be executable to be detected as tasks.
{}

What it means

mise detects file-based tasks in include directories only when the files are executable. If no tasks were defined but the task include directories contain non-executable files that look like candidate tasks, err_no_task throws this error explaining that executability is required, with a hint for making the file executable.

Source

Thrown at src/task/task_list.rs:343

        if let Some(task) = make_task_executable(config, name, task_context).await? {
            return Ok(Some(task));
        }

        // Check if there are non-executable files in task include directories
        if let Some(cwd) = &*dirs::CWD {
            let includes = config::task_includes_for_dir(cwd, &config.config_files)?;
            let excludes = config::task_excludes_for_dir(cwd, &config.config_files)?;
            let non_exec_files = find_non_executable_task_files(&includes, &excludes);
            // The remedy differs by platform and `make_executable_hint` is the only thing that
            // knows how, so it gets one file to name rather than the list. The count and the
            // directories below still say how much is affected.
            if let Some(first) = non_exec_files.first() {
                let dirs_with_files: Vec<String> = includes
                    .iter()
                    .filter(|d| d.is_dir())
                    .map(display_path)
                    .collect();
                bail!(
                    "no tasks defined in {}, but found {} non-executable file(s) in {}.\n\
                        Files must be executable to be detected as tasks.\n\
                        {}",
                    display_path(dirs::CWD.clone().unwrap_or_default()),
                    non_exec_files.len(),
                    dirs_with_files.join(", "),
                    file::make_executable_hint(first),
                );
            }
        }

        bail!(
            "no tasks defined in {}. Are you in a project directory?",
            display_path(dirs::CWD.clone().unwrap_or_default())
        );
    }
    if let Some(task) = make_task_executable(config, name, task_context).await? {
        return Ok(Some(task));

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Make the task scripts executable: `chmod +x .mise/tasks/*` (or the specific file per the hint in the error)
  2. Re-checkout/extract the repo preserving file modes (git config core.fileMode true, tar -p)
  3. If the files are not meant to be tasks, move them out of the task include directory
  4. Prefer defining tasks in mise.toml [tasks] section instead of file-based tasks if executability is hard to maintain

Example fix

# before
$ ls -l .mise/tasks/build   # -rw-r--r--

# after
$ chmod +x .mise/tasks/build
$ mise tasks
Defensive patterns

Strategy: validation

Validate before calling

find .mise/tasks -type f ! -perm -u+x -print 2>/dev/null | head -1 && [ -n "$(find .mise/tasks -type f ! -perm -u+x 2>/dev/null)" ] && chmod +x .mise/tasks/*

Prevention

When it happens

Trigger: A task include directory (e.g. .mise/tasks/ or mise.toml [tasks].include dir) contains script files lacking the executable bit, and no other tasks are defined; running any `mise run <name>` or `mise tasks` then fails.

Common situations: Checked out task scripts on a filesystem that dropped the +x bit (FAT/exFAT mount, Windows checkout, tar extraction without permissions); wrote a new task script with `echo >` and forgot `chmod +x`.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/64d9837f2f408595. Report an issue: GitHub.