{"record":{"id":"f82f0893655dcf26","repo":"vercel/turborepo","slug":"skipping-automatic-task-caching-file-accessed-ou","errorCode":null,"errorMessage":"skipping automatic task caching - file accessed outside of repo root ({unescaped_str})","messagePattern":"skipping automatic task caching - file accessed outside of repo root \\((.+?)\\)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/turborepo-lib/src/run/task_access.rs","lineNumber":114,"sourceCode":"    pub fn can_cache(&self, repo_root: &AbsoluteSystemPathBuf) -> bool {\n        // network\n        if self.accessed.network {\n            turborepo_log::warn(\n                turborepo_log::Source::turbo(turborepo_log::Subsystem::TaskAccess),\n                \"skipping automatic task caching - detected network access\",\n            )\n            .emit();\n            return false;\n        }\n\n        // file system\n        for unescaped_str in &self.accessed.file_paths {\n            match AbsoluteSystemPathBuf::new(unescaped_str.to_string()) {\n                Ok(path) => {\n                    let relation = path.relation_to_path(repo_root);\n                    // only paths within the repo can be automatically cached\n                    if relation == PathRelation::Parent || relation == PathRelation::Divergent {\n                        turborepo_log::warn(\n                            turborepo_log::Source::turbo(turborepo_log::Subsystem::TaskAccess),\n                            format!(\n                                \"skipping automatic task caching - file accessed outside of repo \\\n                                 root ({unescaped_str})\"\n                            ),\n                        )\n                        .emit();\n                        return false;\n                    }\n                }\n                Err(e) => {\n                    debug!(\"failed to parse path {unescaped_str}: {e}\");\n                }\n            }\n        }\n\n        for output in &self.outputs {\n            let output = output.strip_prefix('!').unwrap_or(output.as_str());","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/vercel/turborepo/blob/f9245100cf0d31d96628804ead485f6bf226e55a/crates/turborepo-lib/src/run/task_access.rs#L96-L132","documentation":"In automatic (traced) caching mode, TaskAccess::can_cache (crates/turborepo-lib/src/run/task_access.rs:106-121) checks every file path the task accessed; a path whose relation to the repo root is Parent or Divergent (i.e. outside the repository) makes the task non-cacheable, since cache replay cannot reproduce external file state. The offending path is included in the message.","triggerScenarios":"The task's access trace contains absolute paths resolving above the repo root or on another tree — e.g. reads from ~/.config, /etc, /usr/lib/node_modules, a sibling checkout, or a symlink escaping the repo. AbsoluteSystemPathBuf::new succeeds for these, relation_to_path classifies them Parent/Divergent, and can_cache returns false.","commonSituations":"Tools reading user-level config or caches (~/.npm, ~/.cache, ~/Library), monorepos referencing sibling projects via ../, symlinked node_modules pointing outside the workspace, and containerized builds touching host paths.","solutions":["Identify the reported path and make the task read an in-repo copy instead (commit config, vendor the dependency, or generate it in an earlier cached task).","Give the task explicit inputs/outputs in turbo.json so caching is declared rather than inferred from the trace.","Fix symlinks that escape the repo (hoisted/external node_modules) so all accessed files resolve inside the workspace.","Set env/config so tools use in-repo caches (e.g. npm_config_cache=.npm-cache inside the package)."],"exampleFix":"# before: script reads config above the repo\nimport conf from '../../../shared-config.json'   # -> file accessed outside of repo root\n\n# after: keep the dependency inside the workspace\nimport conf from '../../shared-config.json'   # or declare it as an explicit input","handlingStrategy":"validation","validationCode":"#!/usr/bin/env bash\n# detect repo-escaping file references before running with auto-caching\nROOT=$(git rev-parse --show-toplevel)\ngrep -rnE \"(\\.\\./){2,}|(^|['\\\"])/(etc|usr|home|Users)/\" \\\n  --include=package.json --include=*.config.* \"$ROOT/packages\" \\\n  && echo \"review paths outside repo root — auto-caching will skip these tasks\" >&2\n# exit 0 intentionally; this is advisory","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep all files a cached task reads inside the workspace; vendor external config.","Redirect tool caches into the repo (npm_config_cache, XDG_CACHE_HOME under .turbo).","Avoid symlinks that resolve above the repo root in build inputs."],"tags":["turborepo","caching","task-tracing","filesystem","path-escape"],"backgroundTag":"task-not-cacheable","analyzedSha":"f9245100cf0d31d96628804ead485f6bf226e55a","analyzedAt":"2026-08-17T10:46:15.696Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}