Skip to content

fix: Support turbo watch in single-package workspaces#12460

Merged
anthonyshew merged 3 commits intomainfrom
shew/investigate-9531
Mar 27, 2026
Merged

fix: Support turbo watch in single-package workspaces#12460
anthonyshew merged 3 commits intomainfrom
shew/investigate-9531

Conversation

@anthonyshew
Copy link
Copy Markdown
Contributor

Summary

Fixes #9531

turbo watch crashed in single-package workspaces because the PackageChangesWatcher (the in-process file watcher that powers watch mode) was completely unaware of single-package mode:

  1. PackageGraphBuilder defaulted to multi-package mode, tried to discover workspace globs, and failed with "no workspaces found" — silently killing the watcher.
  2. UnifiedTurboJsonLoader::workspace() was always used instead of ::single_package(), which loads turbo.json differently for non-monorepo projects.
  3. Root package file changes were silently dropped because has_root_tasks() checks for //-prefixed task names, which don't exist in single-package turbo.json files. In single-package mode, the root is the only package, so all change events must propagate.

How to test

  1. Create a single-package workspace (no workspaces field in package.json)
  2. Add a turbo.json with tasks (e.g. {"tasks": {"lint": {}}})
  3. Run turbo watch lint
  4. Verify it starts and re-runs on file changes (previously crashed with "discovery failed: no workspaces found")

The PackageChangesWatcher was unaware of single-package mode, causing
PackageGraphBuilder to fail with 'no workspaces found' when building
the file watcher's internal package graph. Thread the single_package
flag from the watch client through to the watcher so it correctly
builds the graph and loads turbo.json for non-monorepo projects.

Closes #9531
In single-package mode, all files belong to the root package and all
tasks are root tasks. The has_root_tasks() check was filtering out
root package change events because single-package turbo.json tasks
aren't //-prefixed, causing file changes to never trigger re-runs.

Also fixes rustfmt formatting in test helper.
@anthonyshew anthonyshew requested a review from a team as a code owner March 27, 2026 06:27
@anthonyshew anthonyshew requested review from tknickman and removed request for a team March 27, 2026 06:27
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Mar 27, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
examples-basic-web Ready Ready Preview, Comment, Open in v0 Mar 27, 2026 6:40am
examples-designsystem-docs Ready Ready Preview, Comment, Open in v0 Mar 27, 2026 6:40am
examples-gatsby-web Ready Ready Preview, Comment, Open in v0 Mar 27, 2026 6:40am
examples-kitchensink-blog Ready Ready Preview, Comment, Open in v0 Mar 27, 2026 6:40am
examples-nonmonorepo Ready Ready Preview, Comment, Open in v0 Mar 27, 2026 6:40am
examples-svelte-web Ready Ready Preview, Comment, Open in v0 Mar 27, 2026 6:40am
examples-tailwind-web Ready Ready Preview, Comment, Open in v0 Mar 27, 2026 6:40am
examples-vite-web Ready Ready Preview, Comment, Open in v0 Mar 27, 2026 6:40am
turbo-site Ready Ready Preview, Comment, Open in v0 Mar 27, 2026 6:40am
turborepo-agents Ready Ready Preview, Comment, Open in v0 Mar 27, 2026 6:40am

Args::parse() only set single_package on Command::Run, never on
Command::Watch. In the normal shim flow this was masked because
set_run_flags compensates via repo_state, but with --skip-infer
(or any path where repo_state is None) the flag was silently lost.
@anthonyshew anthonyshew merged commit ae78ce1 into main Mar 27, 2026
87 of 89 checks passed
@anthonyshew anthonyshew deleted the shew/investigate-9531 branch March 27, 2026 14:43
github-actions Bot added a commit that referenced this pull request Mar 27, 2026
## Release v2.8.21-canary.17

Versioned docs: https://v2-8-21-canary-17.turborepo.dev

### Changes

- release(turborepo): 2.8.21-canary.16 (#12461) (`e79a56b`)
- fix: Support `turbo watch` in single-package workspaces (#12460)
(`ae78ce1`)

Co-authored-by: Turbobot <turbobot@vercel.com>
github-actions Bot added a commit that referenced this pull request Mar 28, 2026
## Release v2.8.21

Versioned docs: https://v2-8-21.turborepo.dev

### Changes

- release(turborepo): 2.8.20 (#12396) (`45230ec`)
- fix: Disable husky hooks in `update-examples` workflow (#12397)
(`56b79ff`)
- docs: Add link to Docker guide in prune --docker flag section (#12401)
(`e7f0db7`)
- feat: Add `global` configuration key behind
`futureFlags.globalConfiguration` (#12399) (`5f190cf`)
- chore: Update CODEOWNERS to remove /docs owner (#12402) (`3233d3a`)
- fix: Strip JSX components from heading anchors and TOC entries
(#12404) (`3abe553`)
- fix: Move docs app icons into app/ directory (#12403) (`ddf3918`)
- feat: Add experimental structured logging with `--json` and
`--log-file` flags (#12405) (`7ca0601`)
- release(turborepo): 2.8.21-canary.1 (#12407) (`adebb95`)
- docs: Downgrade Next.js (#12408) (`281e89b`)
- chore: Deprecate the `turbo scan` command (#12406) (`4a12c26`)
- release(turborepo): 2.8.21-canary.2 (#12409) (`b9ef212`)
- fix(eslint-plugin-turbo): Guard against missing tasks/pipeline in
forEachTaskDef (#12411) (`6c107c2`)
- release(turborepo): 2.8.21-canary.3 (#12413) (`a2e6635`)
- chore: Upgrade Next.js (#12415) (`b9e6174`)
- Revert "fix: Flush stale mouse tracking events from stdin during TUI
cleanup" (#12416) (`646b06e`)
- fix: Add NixOS environment variables to default passthroughs (#12417)
(`4f12c69`)
- release(turborepo): 2.8.21-canary.4 (#12419) (`19cb539`)
- fix: Resolve security vulnerabilities in `tar` and `rustls-webpki`
(#12418) (`f09b138`)
- release(turborepo): 2.8.21-canary.5 (#12420) (`8aca047`)
- docs: Promote `turbo query` from experimental to stable (#12421)
(`0692aba`)
- docs: Clarify `turbo-ignore`'s future (#12422) (`c5a8235`)
- release(turborepo): 2.8.21-canary.6 (#12423) (`3ebf536`)
- feat: Rework turbo ls to use query internals and add turbo query ls
shorthand (#12424) (`84fd6e3`)
- docs: Clarify environment variables across packages dependency
behavior (#12390) (`e44b0d8`)
- docs: Expand subpath imports example (#12412) (`a7fec57`)
- fix(examples): Update of `with-svelte` example (#11952) (`41d1b2e`)
- release(turborepo): 2.8.21-canary.7 (#12425) (`7155a67`)
- fix: Preserve source dependencies when adding workspace deps in
`turbo-gen` (#11935) (`01c56cc`)
- docs: Add Git history requirements to `turbo query affected` docs
(#12426) (`edc16d5`)
- fix: Prevent horizontal overflow from long inline code on narrow
viewports (#12428) (`a5d641b`)
- release(turborepo): 2.8.21-canary.8 (#12429) (`46814d0`)
- feat: Send git SHA and dirty hash to remote cache (#12427) (`192034a`)
- fix: Upgrade tokio to 1.47.1+ to fix pidfd_reaper panic (#12431)
(`8c25d47`)
- release(turborepo): 2.8.21-canary.9 (#12432) (`2e2f8c3`)
- fix: Use script-shell=bash for cross-platform with-shell-commands
example (#12436) (`d5c2192`)
- docs: Add AI guide to sidebar navigation (#12438) (`021d288`)
- docs: Move `experimentalObservability` into `futureFlags` section
(#12439) (`85812cc`)
- fix: Skip Unix domain sockets and other special files during file
hashing (#12445) (`eb8f75e`)
- fix: Preserve dedupePeers and unknown pnpm lockfile settings (#12443)
(`1529b92`)
- release(turborepo): 2.8.21-canary.10 (#12446) (`014111c`)
- fix: Align dry run cache status with normal run by checking caching
guards (#12448) (`48aa171`)
- release(turborepo): 2.8.21-canary.11 (#12450) (`b14aa0b`)
- fix: Resolve turbo watch hang with mixed interruptible persistent
tasks (#12449) (`326532d`)
- release(turborepo): 2.8.21-canary.12 (#12451) (`379d47b`)
- fix: Avoid `setsid()` in PTY spawn to prevent macOS Gatekeeper CPU
spikes (#12452) (`dcc9f6a`)
- release(turborepo): 2.8.21-canary.13 (#12453) (`19f46e6`)
- feat: Add `packagesFromLockfile()` NAPI binding to `@turbo/repository`
(#12454) (`c58ee79`)
- release(library): 0.0.1-canary.21 (#12455) (`3637185`)
- release(turborepo): 2.8.21-canary.14 (#12456) (`3f87769`)
- refactor: Move cache hit SHA context to verbose logging (#12435)
(`23c15b4`)
- release(turborepo): 2.8.21-canary.15 (#12457) (`6353482`)
- docs: Add missing --force flag documentation (#12440) (`e3b89b0`)
- fix: Prevent panic in turbo watch with persistent tasks (#12459)
(`337b2e8`)
- release(turborepo): 2.8.21-canary.16 (#12461) (`e79a56b`)
- fix: Support `turbo watch` in single-package workspaces (#12460)
(`ae78ce1`)
- release(turborepo): 2.8.21-canary.17 (#12463) (`0bafae2`)
- fix: Missing deps after npm lockfile parsing (#12464) (`fe5a86e`)
- release(turborepo): 2.8.21-canary.18 (#12465) (`c014134`)
- docs: Add AI agent detection and automatic markdown rewrites (#12462)
(`50bd872`)
- fix: Resolve generator name conflicts across workspaces (#12467)
(`d5d37a8`)
- release(turborepo): 2.8.21-canary.19 (#12468) (`7552e93`)
- fix: Remove root package.json from `--affected` global triggers
(#12469) (`91ebb97`)
- release(turborepo): 2.8.21-canary.20 (#12470) (`c5a4690`)
- fix: Show run summary after TUI exits (#12471) (`ffa47d1`)

---------

Co-authored-by: Turbobot <turbobot@vercel.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

turbo watch does not work in single-package workspaces

1 participant