这是indexloc提供的服务,不要输入任何密码
Skip to content

Arbitrary passthrough arguments should not change task hash of dependencies #11025

@eug-vs

Description

@eug-vs

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 (^build should be cached after this)
  • Run turbo lint -- --fix
  • Observe that ^build was re-run (task hash changed)
  • Expected behavior: ^build should have cache-hit, task hash should stay the same

Deeper dive:

  • rm -rf .turbo
  • turbo lint
  • turbo lint --dry-run=json -- --fix
  • Observe that:
    {
      "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"
      ],
      ...
    }

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.

Docs on global hash inputs:

Arbitrary passthrough arguments: turbo build -- --arg=value will miss cache when compared to either turbo build or turbo 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind: bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions