jdx/mise · error

task {} cache command input must not be empty: {command:?}

Error message

task {} cache command input must not be empty: {command:?}

What it means

validate_config scans task.cache.command_inputs for entries that are empty after trimming (command.trim().is_empty()). Command inputs are hashed into the cache key, and an empty command would execute nothing while looking like a real input, so the config is rejected.

Source

Thrown at src/task/task_cache.rs:1219

}

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
        );
    }
    let patterns = task.outputs.patterns();
    if !patterns.is_empty() && output_glob_patterns(&patterns).is_empty() {
        bail!(
            "task {} cache outputs require at least one non-excluded pattern",
            task.name
        );
    }
    for output in &patterns {
        let path = if let Some(body) = output.strip_prefix('!') {
            PathBuf::from(body)
        } else if let Some(body) = output.strip_prefix("\\!") {
            PathBuf::from(format!("!{body}"))
        } else {
            PathBuf::from(&output)

View on GitHub (pinned to 6f52dcdf99)

Solutions

  1. Remove empty or whitespace-only entries from command_inputs
  2. Guard templated commands so unset variables don't render an empty item
  3. Replace placeholder entries with a real, always-valid command (e.g. 'true' is still questionable — prefer removing)

Example fix

# before
[tasks.build]
cache = true
command_inputs = ["git rev-parse HEAD", "{{env.EXTRA_CMD}}"]  # EXTRA_CMD unset -> ""

# after
[tasks.build]
cache = true
command_inputs = ["git rev-parse HEAD"]
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():
    cache = t.get('cache', {})
    if any(not str(c).strip() for c in cache.get('command_inputs', [])):
        sys.exit(f'{name}: empty command_inputs entry')
print('ok')
EOF

Prevention

When it happens

Trigger: Declaring command_inputs = [""] or ["git rev-parse --short HEAD", " "] — any whitespace-only string in the list triggers the bail with the offending entry shown via {command:?}.

Common situations: Templating that renders an optional command to an empty string (e.g. '{{env.GIT_CMD}}' unset); YAML/TOML copy-paste leaving a blank line parsed as an empty item; generated configs that join possibly-empty variables.

Related errors


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