vercel/turborepo · warning

{message}

Error message

{message}

What it means

In `turbo watch`, each rebuilt run constructs a fresh RunBuilder with its own LogSinks (crates/turborepo-lib/src/run/watch.rs:341-352). Like the one-shot run command, it checks turborepo_shim::GLOBAL_WARNING_ENV_VAR — set by the shim when it fell back to the globally installed turbo — re-emits the stored message as a Shim-subsystem warning through the new sinks, then removes the variable so it prints once per watch session.

Source

Thrown at crates/turborepo-lib/src/run/watch.rs:344

            _package_watcher: package_watcher,
            _package_changes_watcher: package_changes_watcher,
            hash_watcher,
        };

        let output_watcher: Arc<dyn OutputWatcher> =
            Arc::new(InProcessOutputWatcher { glob_watcher });

        let new_base = base.clone();
        let mut run_builder =
            RunBuilder::new(new_base, None)?.with_output_watcher(output_watcher.clone());
        if let Some(ref qs) = query_server {
            run_builder = run_builder.with_query_server(qs.clone());
        }
        let sinks = LogSinks::new(base.color_config);
        sinks.init_logger();

        if let Ok(message) = env::var(turborepo_shim::GLOBAL_WARNING_ENV_VAR) {
            turborepo_log::warn(
                turborepo_log::Source::turbo(turborepo_log::Subsystem::Shim),
                message,
            )
            .emit();
            unsafe { env::remove_var(turborepo_shim::GLOBAL_WARNING_ENV_VAR) };
        }

        if verbosity > 0 {
            if let Ok(path) = subscriber.redirect_stderr_to_file(base.repo_root.as_std_path()) {
                tracing::debug!("Verbose tracing redirected to {path}");
            }
        }

        let (run, _analytics) = run_builder.build(&handler, telemetry.clone()).await?;
        let run = Arc::new(run);

        let watched_packages = run.get_relevant_packages();

View on GitHub (pinned to f9245100cf)

Solutions

  1. Install turbo locally: add it to devDependencies with an exact version and run the package manager install so the shim uses node_modules/.bin/turbo.
  2. Confirm the local binary: ./node_modules/.bin/turbo --version should match package.json.
  3. If the global must be used (e.g. a container image), acknowledge the warning or set TURBO_GLOBAL_WARNING_DISABLED=1.
  4. Keep watch sessions on the repo-pinned version to avoid behavior differences between contributors.

Example fix

# before: watch runs on global turbo
npm i -g turbo && turbo watch build   # -> No locally installed `turbo` found...

# after: pin and install locally
"devDependencies": { "turbo": "2.3.3" }
pnpm install
pnpm exec turbo watch build
Defensive patterns

Strategy: validation

Validate before calling

#!/usr/bin/env bash
# guard watch runs on the local binary
if [ ! -x node_modules/.bin/turbo ]; then
  echo "turbo watch requires the repo-local install — run pnpm/npm install" >&2
  exit 1
fi
exec ./node_modules/.bin/turbo watch build

Prevention

When it happens

Trigger: Starting `turbo watch` with a globally installed turbo while the repo has no node_modules/.bin/turbo (turbo missing from devDependencies or dependencies not installed). The shim sets the env var before delegating; the first watch loop iteration relays and clears it.

Common situations: Fresh clones or Docker images relying on global turbo during long watch sessions; version drift where the watcher silently uses a different turbo than the repo pins, which matters for watch reliability and cache compatibility across the team.

Related errors


AI-assisted analysis of vercel/turborepo@f9245100cf (2026-08-17). Data as JSON: /api/errors/0d7336e9a8a14d86. Report an issue: GitHub.