-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Description
Verify canary release
- I verified that the issue exists in the latest Turborepo canary release.
Link to code that reproduces this issue
https://github.com/eug-vs/turbo-args-invalidation-repro
Which canary version will you have in your reproduction?
turbo 2.5.9-canary.10
Environment information
turbo 2.5.9-canary.10
CLI:
Version: 2.5.9-canary.10
Path to executable: /tmp/turbo-args-invalidation-repro/node_modules/.pnpm/turbo-linux-64@2.5.9-canary.10/node_module
s/turbo-linux-64/bin/turbo
Daemon status: Running
Package manager: pnpm9
Platform:
Architecture: x86_64
Operating system: linux
WSL: false
Available memory (MB): 8674
Available CPU cores: 4
Environment:
CI: None
Terminal (TERM): xterm-256color
Terminal program (TERM_PROGRAM): unknown
Terminal program version (TERM_PROGRAM_VERSION): unknown
Shell (SHELL): /bin/zsh
stdin: false
Expected behavior
Passing the CLI arguments turbo task1 task2 -- --arg=value should ONLY change hash (as opposed to the same command without passthrough args) of task1 and task2, and pull other dependency tasks from cache if possible.
--arg=value should ONLY be applied to task1 and task2 (already works as expected)
Actual behavior
Passing the CLI arguments turbo task1 task2 -- --arg=value changes the hash of every task in the dependency tree, resulting in 0 cache hits.
--arg=value should IS ONLY applied to task1 and task2 (correct)
To Reproduce
Reproduction available in this repo: https://github.com/eug-vs/turbo-args-invalidation-repro
Imagine that your lint depends on ^build (e.g you are using compiled internal packages).
Steps to reproduce:
- Run
turbo lint(^buildshould be cached after this) - Run
turbo lint -- --fix - Observe that
^buildwas re-run (task hash changed) - Expected behavior:
^buildshould have cache-hit, task hash should stay the same
Deeper dive:
rm -rf .turboturbo lintturbo lint --dry-run=json -- --fix- Observe that:
Additional context
It might be a known behavior, maybe the docs lack clarification on that.
Docs on turbo run:
[-- [args passed to tasks]]: You may also pass arguments to the underlying scripts. Note that all arguments will be passed to all tasks that are named in the run command.
Arbitrary passthrough arguments:
turbo build -- --arg=valuewill miss cache when compared to eitherturbo buildorturbo build -- --arg=diff
^ The latter example states that it will "miss the cache" and we can guess that it will miss the cache globally for all tasks. It's not quite clear if the deps of build should miss cache as well.
Under the hood, Turborepo creates two hashes: a global hash and a task hash. If either of the hashes change, the task will miss cache.
If this "global" hash was re-calculated for each task, then for "unnamed" tasks (deep in the tree) it would not change since the arguments aren't actually passed through.
This issue effectively makes passthrough arguments unusable in large repos with a lot of compiled packages - adding any -- --arg=value will always miss all the cache with each new flag, even for unrelated tasks.
I apologize if this should've been a discussion rather than an issue.
{ "taskId": "@repo/ui#build", ... "cache": { "local": false, "remote": false, "status": "MISS", "timeSaved": 0 }, "command": "echo Fake build script, called with: $@", // Why is this here? This cliArgs clearly *was not* passed to command, but still affects the hash "cliArguments": [ "--fix" ], ... }