jdx/mise · error

task {} cache requires at least one source

Error message

task {} cache requires at least one source

What it means

validate_config rejects a task enrolled in artifact caching when task.sources is empty. The cache key is derived from source file contents, so with no sources there is nothing to key or invalidate on — caching is meaningless and the config is refused up front.

Source

Thrown at src/task/task_cache.rs:1205

}

fn display_cache_text(text: &str) -> String {
    text.escape_debug().to_string()
}

/// Returns the versioned directory containing task artifact cache entries.
pub(crate) fn task_cache_dir() -> PathBuf {
    Settings::get()
        .task
        .cache_dir
        .clone()
        .unwrap_or_else(|| dirs::CACHE.join("task-artifacts"))
        .join(CACHE_DIR_VERSION)
}

pub(crate) fn validate_config(task: &Task, root: &Path) -> Result<()> {
    if task.sources.is_empty() {
        bail!("task {} cache requires at least one source", task.name);
    }
    if task.outputs.is_auto() {
        bail!(
            "task {} cache requires explicit outputs or outputs = []",
            task.name
        );
    }
    if let Some(command) = task.cache.as_ref().and_then(|cache| {
        cache
            .command_inputs
            .iter()
            .find(|command| command.trim().is_empty())
    }) {
        bail!(
            "task {} cache command input must not be empty: {command:?}",
            task.name
        );
    }

View on GitHub (pinned to 6f52dcdf99)

Solutions

  1. Declare the inputs the task consumes: sources = ["src/**", "mise.toml"]
  2. If the task genuinely has no file inputs, use command_inputs for keying and still declare at least one source (e.g. the config file)
  3. Remove caching from the task if it is inherently non-cacheable

Example fix

# before
[tasks.build]
cache = true
run = "cargo build"

# after
[tasks.build]
cache = true
sources = ["Cargo.toml", "Cargo.lock", "src/**"]
run = "cargo build"
Defensive patterns

Strategy: validation

Validate before calling

python3 - <<'EOF'
import tomllib, sys
cfg = tomllib.load(open('mise.toml','rb'))
for name, t in cfg.get('tasks', {}).items():
    if t.get('cache') and not t.get('sources'):
        sys.exit(f'{name}: cached task needs sources')
print('ok')
EOF

Prevention

When it happens

Trigger: Enabling [task.cache] (or the experimental task artifact caching setting) on a task that declares no sources = [...] list; the check is the first one in validate_config and fires during config validation before any run.

Common situations: Adding cache = true to a deploy or one-off task that only shells out; forgetting the sources line when copying a cached task template; assuming command_inputs alone is enough.

Related errors


AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22). Data as JSON: /api/errors/9c892aede4799be9. Report an issue: GitHub.