{"record":{"id":"07b1f6aa4e6ebeb8","repo":"jdx/mise","slug":"task-cache-requires-explicit-outputs-or-outputs","errorCode":null,"errorMessage":"task {} cache requires explicit outputs or outputs = []","messagePattern":"task (.+?) cache requires explicit outputs or outputs = \\[\\]","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/task/task_cache.rs","lineNumber":1208,"sourceCode":"    text.escape_debug().to_string()\n}\n\n/// Returns the versioned directory containing task artifact cache entries.\npub(crate) fn task_cache_dir() -> PathBuf {\n    Settings::get()\n        .task\n        .cache_dir\n        .clone()\n        .unwrap_or_else(|| dirs::CACHE.join(\"task-artifacts\"))\n        .join(CACHE_DIR_VERSION)\n}\n\npub(crate) fn validate_config(task: &Task, root: &Path) -> Result<()> {\n    if task.sources.is_empty() {\n        bail!(\"task {} cache requires at least one source\", task.name);\n    }\n    if task.outputs.is_auto() {\n        bail!(\n            \"task {} cache requires explicit outputs or outputs = []\",\n            task.name\n        );\n    }\n    if let Some(command) = task.cache.as_ref().and_then(|cache| {\n        cache\n            .command_inputs\n            .iter()\n            .find(|command| command.trim().is_empty())\n    }) {\n        bail!(\n            \"task {} cache command input must not be empty: {command:?}\",\n            task.name\n        );\n    }\n    let patterns = task.outputs.patterns();\n    if !patterns.is_empty() && output_glob_patterns(&patterns).is_empty() {\n        bail!(","sourceCodeStart":1190,"sourceCodeEnd":1226,"githubUrl":"https://github.com/jdx/mise/blob/6f52dcdf99e282ef7a7db68c81301fa4618d0f79/src/task/task_cache.rs#L1190-L1226","documentation":"validate_config requires explicit outputs for cached tasks: task.outputs must not be in Auto mode (TaskOutputs::Auto, i.e. outputs were never declared and mise would auto-manage them). The cache must know exactly which paths to save and restore, so either list output patterns or explicitly opt out with outputs = [].","triggerScenarios":"A cached task whose config omits any outputs key, leaving outputs in auto mode; the is_auto() check is the second validation in validate_config and fires before run.","commonSituations":"Turning on cache for an existing task that never declared outputs; assuming mise will figure out produced files automatically; config generated by a template that drops the outputs field.","solutions":["Declare what the task produces: outputs = [\"target/release/mybin\", \"dist/**\"]","If the task produces nothing worth restoring, declare that explicitly: outputs = []","Re-run after editing to confirm validation passes before depending on the cache"],"exampleFix":"# before\n[tasks.build]\ncache = true\nsources = [\"src/**\"]\nrun = \"cargo build\"\n\n# after\n[tasks.build]\ncache = true\nsources = [\"src/**\"]\noutputs = [\"target/debug/mybin\"]","handlingStrategy":"validation","validationCode":"python3 - <<'EOF'\nimport tomllib, sys\ncfg = tomllib.load(open('mise.toml','rb'))\nfor name, t in cfg.get('tasks', {}).items():\n    if t.get('cache') and 'outputs' not in t:\n        sys.exit(f'{name}: cached task needs explicit outputs (or outputs = [])')\nprint('ok')\nEOF","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Cached tasks must declare outputs explicitly — auto outputs are never cacheable","outputs = [] is the explicit 'no files' declaration"],"tags":["mise","task-cache","caching","configuration","validation"],"backgroundTag":"task-cache-config-invalid","analyzedSha":"6f52dcdf99e282ef7a7db68c81301fa4618d0f79","analyzedAt":"2026-08-22T10:14:23.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}