{"record":{"id":"7c1b759b25484de2","repo":"jdx/mise","slug":"output-does-not-exist","errorCode":null,"errorMessage":"output {} does not exist","messagePattern":"output (.+?) does not exist","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/task/task_cache.rs","lineNumber":1309,"sourceCode":"                    if is_output(&matcher, &path, is_dir) {\n                        resolved.insert(rel);\n                    }\n                }\n            }\n            if require_matches && !glob_matched {\n                bail!(\"output pattern {output:?} matched no files\");\n            }\n        } else {\n            let rel = PathBuf::from(&output);\n            let abs = root.join(&rel);\n            let is_dir = fs::symlink_metadata(&abs)\n                .map(|metadata| metadata.is_dir())\n                .unwrap_or(false);\n            if !is_output(&matcher, &abs, is_dir) {\n                continue;\n            }\n            if require_matches && !abs.exists() && fs::symlink_metadata(&abs).is_err() {\n                bail!(\"output {} does not exist\", rel.display());\n            }\n            resolved.insert(rel);\n        }\n    }\n    Ok(resolved.into_iter().collect())\n}\n\nfn remove_nested_roots(mut roots: Vec<PathBuf>) -> Vec<PathBuf> {\n    roots.sort_by_key(|path| path.components().count());\n    let mut result = Vec::<PathBuf>::new();\n    for root in roots {\n        if !result.iter().any(|parent| root.starts_with(parent)) {\n            result.push(root);\n        }\n    }\n    result.sort();\n    result\n}","sourceCodeStart":1291,"sourceCodeEnd":1327,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/task/task_cache.rs#L1291-L1327","documentation":"mise's task cache records which cache output roots it will save/restore. When resolving a task's declared output patterns with match-required semantics (require_matches=true), each non-glob output must actually exist on disk under the task directory. If a declared output path is missing entirely — neither the file/dir itself nor a symlink to it can be stat'ed — mise bails so it never silently caches a task whose outputs weren't produced.","triggerScenarios":"Running a cached task (mise run/task execution with task cache enabled) whose outputs list names a concrete path (non-glob) that the task script did not create, or that was deleted before the cache-save step calls resolve_output_roots(root, require_matches=true). Also triggered when the output only matches the output matcher but abs.exists() is false and fs::symlink_metadata fails (dangling or absent path).","commonSituations":"Config mistakes: typo'd path in [tasks.x].outputs or outputs referencing files written under a different directory; a build tool conditionally skipping output generation; a task script failing silently but exiting 0; outputs created outside the task root; cleaning the output dir between build and cache save.","solutions":["Run the task's script manually and confirm the declared output path is actually created under the task root","Fix the outputs entry in mise.toml (correct path, or use a glob pattern like dist/** if the file name varies)","If an output is legitimately optional/conditional, make the task always create it (e.g. mkdir -p / touch) or remove it from outputs","Check that earlier steps in the task (file_out, depends) actually ran and produced the artifact"],"exampleFix":"// before (mise.toml)\n[tasks.build]\noutputs = [\"dist/bundle.js\"]  # build writes dist/js/bundle.js\n// after\n[tasks.build]\noutputs = [\"dist/js/bundle.js\"]","handlingStrategy":"validation","validationCode":"# before relying on cache, verify declared outputs exist\nfor f in $OUTPUTS; do\n  [ -e \"$f\" ] || [ -L \"$f\" ] || { echo \"missing task output: $f\" >&2; exit 1; }\ndone","typeGuard":null,"tryCatchPattern":"// rust: treat the bail as 'outputs missing', regenerate instead of failing\nmatch resolve_output_roots(&task, &root, true) {\n    Ok(roots) => roots,\n    Err(e) if e.to_string().contains(\"does not exist\") => {\n        rerun_task(&task)?; // regenerate outputs then retry\n        resolve_output_roots(&task, &root, true)?\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Make the task script create every declared output unconditionally (mkdir -p/touch fallbacks)","Use glob patterns for outputs whose exact names can vary","Verify outputs with a smoke run after editing mise.toml outputs","Ensure failing builds propagate non-zero exit codes so the cache-save step never runs"],"tags":["task-cache","mise-tasks","file-not-found","build-artifacts"],"backgroundTag":"file-not-found","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}