Skip to content

fix: Put version in turbo query JSON output instead of a separate banner - #14229

Merged
anthonyshew merged 1 commit into
mainfrom
shew/query-version-json
Sep 24, 2026
Merged

anthonyshew merged 1 commit into
mainfrom
shew/query-version-json

Conversation

@anthonyshew

Copy link
Copy Markdown
Contributor

Summary

turbo query prints JSON, but the • turbo <version> banner is printed before it. When stdout and stderr are merged, the result can't be parsed, so users end up setting TURBO_PRINT_VERSION_DISABLED=1 everywhere. This PR moves the version into the JSON itself. It also makes the version a regular bullet in the run prelude.

turbo query output

For GraphQL queries, --schema, and query affected, the banner is no longer printed. The version is now the first key of the output object:

-• turbo 2.11.3
 {
+  "version": "2.11.3",
   "data": { ... }
 }

Run prelude

For run and watch, the version is now the first bullet of the prelude instead of a separate grey line:

-• turbo 2.11.3
-
+
+   • turbo 2.11.3
    • Packages in scope: @repo/eslint-config, @repo/typescript-config, @repo/ui, docs, web
    • Running build in 5 packages
    • Remote caching disabled

Where the version is printed now:

turbo <command>
  run / watch            -> first bullet of the run prelude
  query (JSON output)    -> "version" key in the JSON document
  everything else        -> existing banner on stderr

Notes

  • TURBO_PRINT_VERSION_DISABLED and CI detection still hide the prelude bullet. The check now lives in turborepo_run::should_print_version().
  • If a run fails before the prelude (for example, because of an invalid turbo.json), the version is no longer printed.
  • run --json now includes the version once, as a log event in the NDJSON stream.
  • turbo query ls --output json is unchanged. It shares its output shape with turbo ls.
  • check_json_output! now asserts that query output starts with a non-empty version key, then strips it so snapshots stay stable across releases.

Manual verification

On the basic_monorepo fixture with a local build:

  • turbo query '{ packages { items { name } } }' 2>&1 parsed directly with JSON.parse, with keys ['version', 'data'].
  • turbo run build --ui=stream showed the version as the first prelude bullet.
  • CI=1 turbo run build --ui=stream omitted the version bullet.

@anthonyshew
anthonyshew requested review from a team and tknickman September 24, 2026 21:43
@vercel

vercel Bot commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

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

Project Deployment Actions Updated
examples-basic-web Ready Ready Preview Sep 24, 2026 9:45pm UTC
examples-designsystem-docs Ready Ready Preview Sep 24, 2026 9:45pm UTC
examples-gatsby-web Ready Ready Preview Sep 24, 2026 9:45pm UTC
examples-kitchensink-blog Ready Ready Preview Sep 24, 2026 9:45pm UTC
examples-nonmonorepo Ready Ready Preview Sep 24, 2026 9:45pm UTC
examples-svelte-web Ready Ready Preview Sep 24, 2026 9:45pm UTC
examples-tailwind-web Ready Ready Preview Sep 24, 2026 9:45pm UTC
examples-vite-web Ready Ready Preview Sep 24, 2026 9:45pm UTC
turbo-site Ready Ready Preview Sep 24, 2026 9:45pm UTC
turborepo-factory Ready Ready Preview Sep 24, 2026 9:45pm UTC

@anthonyshew anthonyshew changed the title fix: Put version in turbo query JSON output instead of a separate banner fix: Put version in turbo query JSON output instead of a separate banner Sep 24, 2026
@anthonyshew
anthonyshew merged commit f74650c into main Sep 24, 2026
51 checks passed
@anthonyshew
anthonyshew deleted the shew/query-version-json branch September 24, 2026 21:53
github-actions Bot added a commit that referenced this pull request Sep 24, 2026
## Release v2.11.4

> [!CAUTION]
> Versioned docs aliasing FAILED. [View
logs](https://github.com/vercel/turborepo/actions/runs/36064254753)

### Changes

- fix: Respect negated global dependencies in affected detection
(#14164) (`83f6d32`)
- chore: Release Turborepo 2.11.3 (#14165) (`53629a0`)
- test: Share Go compilation caches across integration tests (#14166)
(`684edb6`)
- refactor: Add injectable manifest loading to repository graphs
(#14167) (`bfa7ee1`)
- test: Move Go and Cargo scope planning into crate tests (#14168)
(`17bed92`)
- refactor: Extract subprocess-free Go observation assembly (#14169)
(`6aa7584`)
- test: Move Cargo environment hash contracts into crates (#14170)
(`417e7b0`)
- test: Move Cargo output layout matrices to repository contracts
(#14171) (`2f5f2ad`)
- test: Cover Go discovery identities in memory (#14172) (`133dfd1`)
- test: Cover Go hash inputs in repository contracts (#14174)
(`bf40164`)
- test: Move uv hash input contracts into crates (#14175) (`4681950`)
- test: Cover Go task selection in the engine (#14173) (`63960c5`)
- test: Inject uv discovery for native task contracts (#14176)
(`22d279f`)
- test: Inject query contracts over repository graphs (#14177)
(`5cef46a`)
- test: Inject dry-run task summary contracts (#14178) (`526b026`)
- test: Expose prune workspace selection plan (#14179) (`a05ba5d`)
- test: Inject change detection at scope entry point (#14180)
(`91bb563`)
- test: Move uv lock affectedness planning into repository contracts
(#14184) (`8976bb8`)
- test: Use virtual clock for package watcher events (#14181)
(`efd2a5b`)
- test: Move Cargo task query and dry-run planning into contracts
(#14185) (`34cad2f`)
- test: Move uv quality query and dry-run projections into contracts
(#14186) (`a895310`)
- test: Move JavaScript hash and framework projections into contracts
(#14188) (`b07c3b7`)
- test: Cover prune closure and native layout plans in process (#14189)
(`1f20198`)
- test: Cover mixed-toolchain scope filters through injection (#14190)
(`a9345fb`)
- test: Make package watcher suppression and rediscovery deterministic
(#14191) (`3c533c3`)
- test: Inject watch run lifecycle and event collection (#14192)
(`cf435db`)
- test: Move recursive root-script guard into process-free contract
(#14193) (`86fc080`)
- test: Move Go query and summary parity into crate contracts (#14187)
(`d5602e6`)
- test: Remove duplicate CLI filter matrix cases (#14194) (`9679df3`)
- test: Trim duplicate prune materialization cases (#14195) (`4f88f0f`)
- test: Match Go library summary path on Windows (#14197) (`03a2700`)
- test: Cover mixed-toolchain watch task selection in process (#14196)
(`6b6a46e`)
- test: Preserve Windows SystemRoot in strict-env fixture (#14198)
(`8d74590`)
- test: Retain real watch smokes after selection migration (#14199)
(`e27a4e7`)
- fix: Only reject secondary `go.work` files Go reads for workspace
members (#14183) (`69cc2c4`)
- test: Split Go north-star cache invalidation into hash contracts
(#14201) (`2441e33`)
- test: Avoid deleting built prune output in cross-toolchain prune test
(#14202) (`a4caf0b`)
- test: Move turbo.json validation cases into crate contracts (#14203)
(`59f0fc3`)
- chore: Update with-solid example (#14200) (`aef1e05`)
- refactor: Split RunBuilder execution context construction into phases
(#14204) (`fb37817`)
- refactor: Inject remote cache status probe (#14205) (`b58b280`)
- refactor: Inject inputs into config resolution (#14206) (`01f1a11`)
- feat: Add affected query APIs to turborepo-query (#14207) (`6b7e675`)
- refactor: Wire CLI through affected query APIs (#14208) (`742fe18`)
- feat: Add pure microfrontend port resolver (#14209) (`7d70cab`)
- refactor: Inject change detection into affected run paths (#14210)
(`6d0afae`)
- test: Move affectedTasks planning cases into query contracts (#14214)
(`7871007`)
- refactor: Route get-mfe-port through the pure resolver (#14215)
(`3826a04`)
- test: Count native discovery for JavaScript-only selections (#14216)
(`4fa1096`)
- fix: Disable remote cache after unrecoverable forbidden responses
(#14218) (`a0a5dff`)
- perf: Send cache analytics in larger batches (#14219) (`96e20b6`)
- perf: Batch dry-run remote cache existence checks (#14220) (`e1ab2d6`)
- test: Move config precedence cases into funnel contracts (#14217)
(`935c9ea`)
- test: Move affected run planning into RunBuilder contracts (#14212)
(`ec329a0`)
- fix: Coordinate artifact requests after rate limiting (#14221)
(`7353b16`)
- fix: Share concurrent remote-cache token recovery (#14223) (`813bed0`)
- refactor: Make repository context inputs injectable (#14224)
(`58a4889`)
- refactor: Group Run state into execution and services contexts
(#14225) (`4b72ac9`)
- test: Move Cargo prune layout checks into in-process plan contracts
(#14226) (`8a9a10a`)
- test: Move Cargo and Go discovery cases into contracts (#14227)
(`4d72915`)
- fix: Put version in `turbo query` JSON output instead of a separate
banner (#14229) (`f74650c`)

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
github-actions Bot added a commit that referenced this pull request Sep 25, 2026
## Release v2.11.5-canary.1

> [!CAUTION]
> Versioned docs aliasing FAILED. [View
logs](https://github.com/vercel/turborepo/actions/runs/36081266558)

### Changes

- chore: Release Turborepo 2.11.3-canary.4 (#14162) (`fb2fb0c`)
- fix: Stop with tasks when parent exits (#14163) (`fde6637`)
- fix: Respect negated global dependencies in affected detection
(#14164) (`83f6d32`)
- chore: Release Turborepo 2.11.3 (#14165) (`53629a0`)
- test: Share Go compilation caches across integration tests (#14166)
(`684edb6`)
- refactor: Add injectable manifest loading to repository graphs
(#14167) (`bfa7ee1`)
- test: Move Go and Cargo scope planning into crate tests (#14168)
(`17bed92`)
- refactor: Extract subprocess-free Go observation assembly (#14169)
(`6aa7584`)
- test: Move Cargo environment hash contracts into crates (#14170)
(`417e7b0`)
- test: Move Cargo output layout matrices to repository contracts
(#14171) (`2f5f2ad`)
- test: Cover Go discovery identities in memory (#14172) (`133dfd1`)
- test: Cover Go hash inputs in repository contracts (#14174)
(`bf40164`)
- test: Move uv hash input contracts into crates (#14175) (`4681950`)
- test: Cover Go task selection in the engine (#14173) (`63960c5`)
- test: Inject uv discovery for native task contracts (#14176)
(`22d279f`)
- test: Inject query contracts over repository graphs (#14177)
(`5cef46a`)
- test: Inject dry-run task summary contracts (#14178) (`526b026`)
- test: Expose prune workspace selection plan (#14179) (`a05ba5d`)
- test: Inject change detection at scope entry point (#14180)
(`91bb563`)
- test: Move uv lock affectedness planning into repository contracts
(#14184) (`8976bb8`)
- test: Use virtual clock for package watcher events (#14181)
(`efd2a5b`)
- test: Move Cargo task query and dry-run planning into contracts
(#14185) (`34cad2f`)
- test: Move uv quality query and dry-run projections into contracts
(#14186) (`a895310`)
- test: Move JavaScript hash and framework projections into contracts
(#14188) (`b07c3b7`)
- test: Cover prune closure and native layout plans in process (#14189)
(`1f20198`)
- test: Cover mixed-toolchain scope filters through injection (#14190)
(`a9345fb`)
- test: Make package watcher suppression and rediscovery deterministic
(#14191) (`3c533c3`)
- test: Inject watch run lifecycle and event collection (#14192)
(`cf435db`)
- test: Move recursive root-script guard into process-free contract
(#14193) (`86fc080`)
- test: Move Go query and summary parity into crate contracts (#14187)
(`d5602e6`)
- test: Remove duplicate CLI filter matrix cases (#14194) (`9679df3`)
- test: Trim duplicate prune materialization cases (#14195) (`4f88f0f`)
- test: Match Go library summary path on Windows (#14197) (`03a2700`)
- test: Cover mixed-toolchain watch task selection in process (#14196)
(`6b6a46e`)
- test: Preserve Windows SystemRoot in strict-env fixture (#14198)
(`8d74590`)
- test: Retain real watch smokes after selection migration (#14199)
(`e27a4e7`)
- fix: Only reject secondary `go.work` files Go reads for workspace
members (#14183) (`69cc2c4`)
- test: Split Go north-star cache invalidation into hash contracts
(#14201) (`2441e33`)
- test: Avoid deleting built prune output in cross-toolchain prune test
(#14202) (`a4caf0b`)
- test: Move turbo.json validation cases into crate contracts (#14203)
(`59f0fc3`)
- chore: Update with-solid example (#14200) (`aef1e05`)
- refactor: Split RunBuilder execution context construction into phases
(#14204) (`fb37817`)
- refactor: Inject remote cache status probe (#14205) (`b58b280`)
- refactor: Inject inputs into config resolution (#14206) (`01f1a11`)
- feat: Add affected query APIs to turborepo-query (#14207) (`6b7e675`)
- refactor: Wire CLI through affected query APIs (#14208) (`742fe18`)
- feat: Add pure microfrontend port resolver (#14209) (`7d70cab`)
- refactor: Inject change detection into affected run paths (#14210)
(`6d0afae`)
- test: Move affectedTasks planning cases into query contracts (#14214)
(`7871007`)
- refactor: Route get-mfe-port through the pure resolver (#14215)
(`3826a04`)
- test: Count native discovery for JavaScript-only selections (#14216)
(`4fa1096`)
- fix: Disable remote cache after unrecoverable forbidden responses
(#14218) (`a0a5dff`)
- perf: Send cache analytics in larger batches (#14219) (`96e20b6`)
- perf: Batch dry-run remote cache existence checks (#14220) (`e1ab2d6`)
- test: Move config precedence cases into funnel contracts (#14217)
(`935c9ea`)
- test: Move affected run planning into RunBuilder contracts (#14212)
(`ec329a0`)
- fix: Coordinate artifact requests after rate limiting (#14221)
(`7353b16`)
- fix: Share concurrent remote-cache token recovery (#14223) (`813bed0`)
- refactor: Make repository context inputs injectable (#14224)
(`58a4889`)
- refactor: Group Run state into execution and services contexts
(#14225) (`4b72ac9`)
- test: Move Cargo prune layout checks into in-process plan contracts
(#14226) (`8a9a10a`)
- test: Move Cargo and Go discovery cases into contracts (#14227)
(`4d72915`)
- fix: Put version in `turbo query` JSON output instead of a separate
banner (#14229) (`f74650c`)
- chore: Release Turborepo 2.11.4 (#14231) (`5d2e55f`)
- test: Move Python opt-in hint into filter contracts (#14228)
(`f5b6fea`)
- test: Move dependency-output summary assertion into contract (#14230)
(`3ee0227`)
- test: Move dependency-output selection and validation cases to engine
contracts (#14232) (`9bd011f`)
- test: Move Cargo exclude-only scope coverage (#14238) (`c99ad87`)
- test: Move Cargo cache-authority cases to contracts (#14240)
(`1ad8190`)
- test: Move JIT dependency graph scenario into engine contract (#14235)
(`e427a23`)
- test: Move dependency-output hash cases into task-hash contracts
(#14233) (`c17b62c`)
- test: Move Cargo task-filter cases into crate contracts (#14239)
(`fa6b8db`)
- test: Move JIT input hash timing cases into task-hash contracts
(#14234) (`c928e42`)
- test: Move package input normalization cases into engine contracts
(#14236) (`e6c6d77`)
- test: Move structured startup and JIT input cases into contracts
(#14237) (`a29c843`)
- fix: Back off remote artifact requests during outages (#14222)
(`103d81c`)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
greydragon888 added a commit to greydragon888/real-router that referenced this pull request Sep 28, 2026
… banner

- turbo 2.11.4 prints no `• turbo X.Y` banner for `query` or for
  `run --dry=json`: the version moved into the JSON
  (vercel/turborepo#14229). The entry matched nothing since the turbo bump,
  so scripts/tests failed wherever it runs: pre-push and a PR's Repo Lints
- CLIS takes a line only main() prints; `mode=leaf|sharded` is that line,
  and main() reaches it only after parsing turbo's JSON
- Control: with main() printing `plan=` instead, the check fails

This branch was successfully deployed

1 active deployment
Preview – turborepo-factory — 0f830800 Deployed Sep 24, 2026 by vercel[bot]
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.

1 participant