You’ve encountered an interesting behavior difference between turbo run lint and turbo watch lint when it comes to detecting changes in your root-level eslint.config.mjs file.
The Problem
turbo run lint correctly cache misses when eslint.config.mjs changes
turbo watch lint doesn’t rerun when eslint.config.mjs changes, despite it being in the inputs array
Moving the file to globalDependencies fixes the issue for turbo watch
Why This Happens
This appears to be related to how turbo watch handles task-level inputs versus global dependencies. The watcher functionality might not be correctly processing the $TURBO_ROOT$ path prefix in the inputs array.
Solutions
1. Use globalDependencies (Recommended)
Since you’ve already found this solution works, this is the most straightforward approach:
This behavior difference between turbo run and turbo watch for root-level inputs might be a subtle bug in Turborepo. The globalDependencies approach is the most reliable solution since it’s specifically designed to handle files that affect multiple packages.
If you’re interested in the technical details, turbo watch uses a different mechanism for file watching than the dependency graph calculation used by turbo run, which might explain the discrepancy in behavior.
The absolute path doesn’t work either, nor does the glob. I’ll stick with the globalDependencies for now. Is this a bug? If so I could file it in the turborepo repo.