Troubleshooting Runs
As with most tools, it can be frustrating to understand why Turborepo
is not working the way you expect. This page covers some tools to debug when
using the turbo
CLI and some common problems you may encounter.
Enable Verbose Logs
The best debugging tool we have as developers are logs. You can turn up the log
level with the --verbosity
flag. Combined with building from
source, this can be a powerful and flexible way to see what's going on under
the hood.
Check the Run Summary
The --summarize flag generates and saves metadata about your turbo run
as a JSON file in .turbo/runs
. You can use it to compare subsequent runs, inspect
the contents of the cached artifact, and the inputs to the hash for a task.
Check your Configuration
Task Configuration
You can get started with Turborepo with minimal configuration -- that's one
of the things people love about Turborepo! But when you omit configuration,
Turborepo internally falls back to smart defaults. Additionally, when using
Workspace Configurations in a monorepo, it can be
confusing to understand how Turborepo interpreted your turbo.json
. You can use
the --dry
or --dry=json
to get a "resolved" task configuration for any task.
For example:
turbo run build --dry=json
Look for a resolvedTaskConfiguration
key in the output.
User Config
When you link your repository to Vercel, Turborepo stores configuration in two places:
- your Vercel team information is stored in
.turbo/config.json
. You can inspect this file to see what else might be in there! - an authentication token is stored in
~/Library/Application\ Support/turborepo/config.json
.
Inspect the Cache
When turborepo runs a task that has configured outputs
, it caches those
outputs, along with the logs from that task in the node_modules/.cache/turbo/
.
These artifacts are compressed with tar
, but you can uncompress and see what's
in them.
Build from Source
One of the advantages of JavaScript codebases are that you can open up
node_modules/
and edit the code you're running inline. This is not possible
with turbo
, because the runnable code is a compiled binary and you cannot edit
it inline. But because the codebase is Open Source, you can always get
the source code, modify it, and build it locally. The bulk of this
documentation is available in the Contributing Guide (opens in a new tab), but you can use those
directions even if you aren't planning to make a contribution.
- Clone the git repo from
vercel/turbo
(opens in a new tab) cd cli
- Make any changes (for example, add more logging)
- Run
make
- From your project, use
/:path/:to/:turbo/target/debug/turbo
instead of global turbo or the version ofturbo
installed in your project.
Common Pitfalls
Nested workspaces
Turborepo does not support nested workspaces. Therefore, if you have a workspace that contains another workspace, you may see unexpected behavior. We recommend flattening your workspace structure to avoid this issue.
The .turbo
directory
One of the core concepts behind Turbo is that when a declared input changes, the cached outputs for that task are invalidated. As part of running any task, Turborepo creates the following directories:
- A
.turbo
at the root of your repo - A
.turbo
directory in each workspace if your project is a monorepo (e.g.apps/my-app/.turbo/
) - A
turbo
directory innode_modules/.cache
Because the first two directories are not git-ignored by default, you may see an
issue where you run the same task twice and get a cache missing, even though you
didn't change anything, because the generated .turbo
directories are getting included as
the task inputs, and invalidating cache. To avoid this problem, add .turbo
to your
.gitignore
file. Alternatively, you can also limit your inputs
configuration
so that .turbo
is not included in the cache inputs.
Common Questions
I'm not seeing any cache hits
In general, you should expect that when you run turbo run
twice in a row, you should get a
cache hit on the second run. If this isn't happening, run both builds again with the --summarize
flag and compare the generated Run Summaries to each other. In most cases, the
comparison should show why the second run did not get a cache hit.
You can also ask:
-
Is any source code being generated during the build that isn't checked into git?
This would change the fingerprint Turborepo uses to store build outputs.
-
Are cache outputs correctly specified in your Turborepo pipeline?
Pipeline settings are not inherited or merged, so they need to be re-specified in workspace-specific tasks (e.g.
web#build
does not inherit pipeline settings frombuild
). -
Are relevant inlined environment variables accounted for?
Enable verbose mode to see which environment variables are included in the hashes.
I'm seeing cache hits, but my build is broken
-
Are cache outputs properly specified in your Turborepo pipeline?
Pipeline settings are not inherited or merged, so they need to be re-specified in workspace-specific tasks (e.g.
web#build
does not inherit pipeline settings frombuild
).
My build is caching the wrong environment variables
-
Are relevant inlined environment variables accounted for?
Enable verbose mode to see which environment variables are included in the hashes.
Common Monorepo Questions
My dependency isn't being built correctly
-
Are you properly bundling and transpiling the dependency before building the application?
For example, libraries like
tsc
,tsup
,esbuild
,babel
, andswc
will convert newer JavaScript features back to “pure” JavaScript.If you are using Next.js, you might be using
transpilePackages
. Ensure you add the name of the dependency insidenext.config.js
(example (opens in a new tab)). -
Have you listed
files
in the dependency'spackage.json
to point to the correct files?
My types are not being found
-
Did you specify
types
ortyping
inside the dependency'spackage.json
to point to the.d.ts
file? -
Have you altered or set custom
tsconfig.json
paths
?- Do they have the correct folder structure for your application?
- Are they properly configured for the meta framework, bundler, or transpilation tool?