Commit db79c86
fix: respect MASTRA_TELEMETRY_DISABLED across CLI, core, and Studio (#16990)
## Summary
A user reported that setting `MASTRA_TELEMETRY_DISABLED=true` in their
project's `.env` did not stop PostHog network requests from
`localhost:4112` after running `mastra dev`. Investigation found bugs in
**three** places, each with different (and sometimes wrong) handling of
the env var.
This PR integrates [PR
#16921](#16921) (Devin session
for @smthomas — partial overlap) on top of the missing deployer fix that
#16921 didn't address.
### Bugs
| Location | Behavior before | Fix |
|---|---|---|
| `packages/deployer/src/server/index.ts:490` | Hardcoded
`telemetryDisabled: \`''\`` when injecting playground HTML, so
`window.MASTRA_TELEMETRY_DISABLED` was always empty in the browser
regardless of `.env` | Propagate `process.env.MASTRA_TELEMETRY_DISABLED`
into the injected HTML |
| `packages/core/src/telemetry/posthog.ts:13` | Strict `=== '1'` check —
`true`, `yes`, etc. silently kept enterprise telemetry on | Accept `1` /
`true` / `yes` (case-insensitive, trimmed) |
| `packages/cli/src/analytics/index.ts` constructor | Ran disk I/O
(write `mastra-cli.json` with tracking IDs) and generated a distinctId
before checking the env var | Early-return at the top of the constructor
when disabled |
| `packages/playground/src/lib/analytics.tsx` | Plain truthy check —
would have parsed `'false'` as truthy if the dev server had ever
propagated it | Match the canonical `1` / `true` / `yes` parser used
elsewhere |
### Why this is a superset of #16921
PR #16921 modified the playground's parser to use the canonical truthy
values, but it **did not touch
`packages/deployer/src/server/index.ts:490`**. Under #16921 alone,
`window.MASTRA_TELEMETRY_DISABLED` would still be the hardcoded empty
string injected by the dev server, the canonical parser would correctly
return `false` for an empty string, and **the user-reported network
requests would still fire**. The deployer fix in this PR is what
actually stops the reported behavior.
The other three files in this PR are taken verbatim from #16921.
## Test plan
- [x] `vitest run src/telemetry/posthog.test.ts` in `@mastra/core` —
12/12 passing (parameterized matrix from #16921)
- [x] `vitest run src/build/utils.test.ts` in `@mastra/deployer` — 85/85
passing
- [ ] Manual: scaffold a fresh project with `npm create mastra`, set
`MASTRA_TELEMETRY_DISABLED=true` in `.env`, run `mastra dev`, confirm no
PostHog requests in the browser Network tab
- [ ] Manual: same setup without the env var — confirm PostHog requests
still fire (regression check)
- [ ] Manual: confirm `mastra-cli.json` is **not** written when
telemetry is disabled
## Coordination
Should be merged in place of (or with closure of) #16921 since this is a
strict superset. /cc the author of #16921.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## ELI5
There was a setting (MASTRA_TELEMETRY_DISABLED) meant to turn off
analytics, but different parts of the app interpreted it differently or
didn't pass it to the browser. This PR makes the setting consistently
disable telemetry everywhere by (1) sending the env value to the Studio
browser, and (2) treating any common "truthy" value (e.g., "1", "true",
"yes", case-insensitive, trimmed) as "disable telemetry".
## Problem
MASTRA_TELEMETRY_DISABLED was handled inconsistently:
- CLI (packages/cli/src/analytics/index.ts): already treated truthy
values as disabling telemetry (correct).
- Core (packages/core/src/telemetry/posthog.ts): only `'1'` disabled
telemetry, ignoring other truthy values.
- Studio/browser (packages/deployer/src/server/index.ts → playground):
the served HTML injected an empty string, so
window.MASTRA_TELEMETRY_DISABLED was always falsy and browser PostHog
always initialized.
This meant setting MASTRA_TELEMETRY_DISABLED=true in .env didn't
reliably stop PostHog requests.
## Changes
- packages/deployer/src/server/index.ts
- Propagate process.env.MASTRA_TELEMETRY_DISABLED into the injected
Studio HTML template (was hardcoded to empty string), so the browser
sees the actual env value.
- packages/core/src/telemetry/posthog.ts
- Introduced TRUTHY_DISABLED_VALUES = new Set(['1','true','yes']).
- Updated isEETelemetryEnabled() to trim/lowercase the env value and
disable telemetry for any of those truthy values (previously only '1').
- packages/core/src/telemetry/posthog.test.ts
- Updated tests to parameterize telemetry-disabled and telemetry-enabled
cases to cover '1', 'true', 'TRUE', 'yes', ' True ' as disabling, and
values like '0', 'false', 'no', 'off', 'on' as not disabling.
- packages/playground/src/lib/analytics.tsx
- Added matching client-side isTelemetryDisabled() logic reading
window.MASTRA_TELEMETRY_DISABLED and treating '1','true','yes' (trimmed,
lowercased) as disabling telemetry.
- packages/cli/src/analytics/index.ts
- Telemetry enablement remains consistent; CLI already treats those
truthy values as disabling telemetry. The constructor short-circuits
early when telemetry is disabled (avoids disk I/O and PostHog client
creation).
- Changesets
- Release notes updated for `@mastra/deployer` and `@mastra/core`
documenting the fix and canonical truthy disable values.
## Result
MASTRA_TELEMETRY_DISABLED set to any common truthy value (e.g., true, 1,
yes — case-insensitive, trimmed) now consistently disables telemetry
across CLI, core (server-side), and the browser-based Studio/playground.
When disabled, PostHog clients are not constructed and no telemetry
network requests are made.
## Tests
- Unit: core telemetry tests updated and passing (5/5); deployer build
utils (85/85) unchanged/passing per test plan.
- Manual: documented manual steps to scaffold a project and verify
PostHog requests stop when toggling MASTRA_TELEMETRY_DISABLED.
## Reviewer question
Core previously only disabled telemetry for the literal string '1' and
had a dedicated test that suggested intentional strictness. If strict
behavior should be preserved, revert the core change and document that
only MASTRA_TELEMETRY_DISABLED=1 is canonical. Otherwise, this PR's
relaxed behavior (accepting '1', 'true', 'yes') ensures consistent and
user-friendly opt-out handling across components.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/mastra-ai/mastra/pull/16990?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent ab7e12c commit db79c86
7 files changed
Lines changed: 69 additions & 17 deletions
File tree
- .changeset
- packages
- cli/src/analytics
- core/src/telemetry
- deployer/src/server
- playground/src/lib
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
30 | 30 | | |
31 | 31 | | |
32 | 32 | | |
33 | | - | |
| 33 | + | |
34 | 34 | | |
35 | | - | |
| 35 | + | |
36 | 36 | | |
37 | | - | |
| 37 | + | |
38 | 38 | | |
39 | 39 | | |
40 | 40 | | |
| |||
46 | 46 | | |
47 | 47 | | |
48 | 48 | | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
49 | 54 | | |
50 | 55 | | |
51 | 56 | | |
| |||
71 | 76 | | |
72 | 77 | | |
73 | 78 | | |
74 | | - | |
75 | | - | |
76 | | - | |
| 79 | + | |
77 | 80 | | |
78 | 81 | | |
79 | 82 | | |
| |||
99 | 102 | | |
100 | 103 | | |
101 | 104 | | |
102 | | - | |
103 | | - | |
104 | | - | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
105 | 108 | | |
106 | 109 | | |
107 | | - | |
108 | 110 | | |
109 | 111 | | |
110 | 112 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
31 | 31 | | |
32 | 32 | | |
33 | 33 | | |
34 | | - | |
35 | | - | |
| 34 | + | |
| 35 | + | |
36 | 36 | | |
37 | 37 | | |
38 | 38 | | |
39 | 39 | | |
40 | 40 | | |
41 | 41 | | |
42 | 42 | | |
43 | | - | |
44 | | - | |
| 43 | + | |
| 44 | + | |
45 | 45 | | |
46 | 46 | | |
47 | 47 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
7 | 8 | | |
8 | 9 | | |
9 | 10 | | |
10 | 11 | | |
11 | 12 | | |
12 | 13 | | |
13 | | - | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
14 | 19 | | |
15 | 20 | | |
16 | 21 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
487 | 487 | | |
488 | 488 | | |
489 | 489 | | |
490 | | - | |
| 490 | + | |
491 | 491 | | |
492 | 492 | | |
493 | 493 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
6 | 16 | | |
7 | 17 | | |
8 | 18 | | |
9 | 19 | | |
10 | 20 | | |
11 | 21 | | |
12 | 22 | | |
13 | | - | |
| 23 | + | |
14 | 24 | | |
15 | 25 | | |
16 | 26 | | |
| |||
0 commit comments