Turbo only cache files at the start of a command, resulting in erroneous format/linting cache hit
Verify canary release
- [x] I verified that the issue exists in the latest Turborepo canary release.
Link to code that reproduces this issue
https://github.com/BayLee4/turbo-bug
Which canary version will you have in your reproduction?
2.4.5-canary.2
Enviroment information
turbo 2.4.5-canary.2
CLI:
Version: 2.4.5-canary.2
Path to executable: ~/Downloads/turbo-bug/node_modules/turbo-darwin-arm64/bin/turbo
Daemon status: Running
Package manager: pnpm9
Platform:
Architecture: aarch64
Operating system: macos
WSL: false
Available memory (MB): 13176
Available CPU cores: 11
Environment:
CI: None
Terminal (TERM): xterm-ghostty
Terminal program (TERM_PROGRAM): ghostty
Terminal program version (TERM_PROGRAM_VERSION): 1.1.2
Shell (SHELL): /bin/zsh
stdin: false
Expected behavior
Turbo should not hit cache when a source file hash has changed
Actual behavior
Turbo hits cache when a source file hash has changed
To Reproduce
pnpm install
yes | pnpm dlx shadcn@canary add button -c packages/ui # will modify button.tsx
pnpm format --filter=@workspace/ui # correctly restore it to baseline (no cache hit)
yes | pnpm dlx shadcn@canary add button -c packages/ui # will modify it again
pnpm format --filter=@workspace/ui # cache hit, full turbo, format skipped
Additional context
I verified using --summarize that the hash is correctly updated between commands, but it still hit cache
Hi, thanks for the issue. Could you paste the --summarize output here? I'm a little confused since in my testing yes | pnpm dlx shadcn@canary add button -c packages/ui should produce the same button.tsx file, so each call to pnpm format --filter=@workspace/ui should get the same input and therefore hit cache.
Hi :wave:
You're right that the shadcn@canary add button produce the same button.tsx file, it is the format command that modifies it (due to prettier-plugin-tailwindcss reordering the classes) back to its git original state
I tried to run with --summarize again and got the same hashes using the exact commands above, don't know where I got that info the first place, sorry for the mislead 🤷♂
But I think I understand the issue now, it seems what is cached is only the pre-format hash of button.tsx, meaning we have something like this:
- Git clone,
button.tsxhashash_1 - First
shadcn@canarycommand,button.tsxis modified (hash_2) - First format command, cache miss,
hash_2is cached and format is ran, formattingbutton.tsxback to its original statehash_1 - Second
shadcn@canarycommand, back tohash_2 - Second format command, cache hit with
hash_2, format return with success - Bug, the format command has not worked despite turbo indicating otherwise
It seems the bug comes from the turbo caching mechanism only calculating input files hashes at start, which is not an issue for build commands but create the following bug for linter/format commands
Gotcha. For a formatting task, you could either disable caching for it, or you could try making the task outputs the source files. That way if you hit cache, Turborepo should restore the source files. That does create some potential problems if you're using watch mode, because a task could end up in an infinite loop, but as long as you're not using watch mode, it should work.
I see, I think I'll just disable caching for lint/format command for now, that way I'll avoid the mega headache inevitably coming when I'll forget about the workaround and wonders why watch is breaking.
On the resolution side, would caching input files at the end of a task (just like output files) be a reasonable solution to you?