Skip to content

Telemetry: Fix delayed init events#34670

Merged
JReinhold merged 8 commits into
nextfrom
jeppe/fix-init-telemetry
May 1, 2026
Merged

Telemetry: Fix delayed init events#34670
JReinhold merged 8 commits into
nextfrom
jeppe/fix-init-telemetry

Conversation

@JReinhold
Copy link
Copy Markdown
Contributor

@JReinhold JReinhold commented Apr 30, 2026

Closes #

What I did

We found that during init, telemetry events would not be sent until the very end of the flow, where everything would be sent at once. If the flow was canclled mid-way, no events would be sent.

This change ensures that events are sent when they happen.

This was originally a regression from #34485 which was released in 10.4.0-alpha.10, so it's only a small window of bad telemetry.

Now, we immediately resolve telemetry state, instead of relying on the different commands do to it eventually from their loaded presets.
There's a small change here, where previously we would use preset loading mechanism to look up core.disableTelemetry but now we just load the main config, because it's faster. So theoretically someone could have an external preset where they set telemetry setting and that wouldn't be supported anymore, now we only support it when it's directly set in main.ts (although it can be imported from elsewhere, etc.)

Checklist for Contributors

Testing

The changes in this PR are covered in the following automated tests:

  • stories
  • unit tests
  • integration tests
  • end-to-end tests

Manual testing

Caution

This section is mandatory for all contributions. If you believe no manual test is necessary, please state so explicitly. Thanks!

Documentation

  • Add or update documentation reflecting your changes
  • If you are deprecating/removing a feature, make sure to update
    MIGRATION.MD

Checklist for Maintainers

  • When this PR is ready for testing, make sure to add ci:normal, ci:merged or ci:daily GH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found in code/lib/cli-storybook/src/sandbox-templates.ts

  • Make sure this PR contains one of the labels below:

    Available labels
    • bug: Internal changes that fixes incorrect behavior.
    • maintenance: User-facing maintenance tasks.
    • dependencies: Upgrading (sometimes downgrading) dependencies.
    • build: Internal-facing build tooling & test updates. Will not show up in release changelog.
    • cleanup: Minor cleanup style change. Will not show up in release changelog.
    • documentation: Documentation only changes. Will not show up in release changelog.
    • feature request: Introducing a new feature.
    • BREAKING CHANGE: Changes that break compatibility in some way with current major version.
    • other: Changes that don't fit in the above categories.

🦋 Canary release

This PR does not have a canary release associated. You can request a canary release of this pull request by mentioning the @storybookjs/core team here.

core team members can create a canary release here or locally with gh workflow run --repo storybookjs/storybook publish.yml --field pr=<PR_NUMBER>

Summary by CodeRabbit

  • Refactor
    • Telemetry preference is resolved earlier during startup and now uses a defined fallback behavior for unresolved cases, making initialization telemetry more consistent.
  • Tests
    • Expanded telemetry initialization tests to cover CLI opt‑in, config‑derived settings, fallback behavior, and related edge cases.
  • Chores
    • Test setup updated to ignore a specific Browserslist warning pattern.

@JReinhold JReinhold moved this to In Progress in Core Team Projects Apr 30, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses a regression in create-storybook init telemetry where events were being queued and only flushed at the end of the init flow (meaning mid-flow cancellation could result in no events being sent). It resolves telemetry state earlier so init-time events are emitted when they occur.

Changes:

  • Import and invoke setTelemetryEnabled() at the start of the withTelemetry('init', ...) run callback.
  • Ensure init telemetry is not delayed until the end of the init orchestration flow.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread code/lib/create-storybook/src/initiate.ts Outdated
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 30, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 916202e3-26ba-47b5-a5fa-742add5657f5

📥 Commits

Reviewing files that changed from the base of the PR and between 80b7338 and 79a2f71.

📒 Files selected for processing (1)
  • code/vitest-setup.ts
✅ Files skipped from review due to trivial changes (1)
  • code/vitest-setup.ts

📝 Walkthrough

Walkthrough

Telemetry initialization is centralized and resolved earlier: CLI opt-in is applied immediately, otherwise main config is loaded (default .storybook) to determine telemetry, with a configurable fallback. Several callers no longer toggle telemetry directly; tests updated to cover resolution ordering and failures.

Changes

Cohort / File(s) Summary
Init / create-storybook
code/lib/create-storybook/src/initiate.ts
Await explicit telemetry enablement via setTelemetryEnabled(!options.disableTelemetry) before doInitiate; call withTelemetry('init', ...) with fallbackTelemetryState: true.
Core server startup
code/core/src/core-server/build-dev.ts, code/core/src/core-server/build-static.ts
Removed imports/calls to setTelemetryEnabled and explicit telemetry toggle from dev/static startup; telemetry event emissions remain.
Presets / server channel
code/core/src/core-server/presets/common-preset.ts
Removed preset-derived coreOptions lookup and the early setTelemetryEnabled call from the experimental server channel.
Telemetry core logic & tests
code/core/src/core-server/withTelemetry.ts, code/core/src/core-server/withTelemetry.test.ts
Refactored telemetry init into resolveTelemetryState() that prefers CLI disableTelemetry, otherwise loads loadMainConfig({ configDir }), falls back to fallbackTelemetryState (new TelemetryOptions.fallbackTelemetryState?: boolean); tests expanded to validate resolution order and failure handling.
Test setup
code/vitest-setup.ts
Adjusted ignore regex to suppress specific Browserslist console warnings.

Sequence Diagram(s)

sequenceDiagram
  participant CLI as CLI / Init caller
  participant WithTelemetry as withTelemetry
  participant Config as loadMainConfig
  participant Telemetry as setTelemetryEnabled / telemetry
  participant Runner as doInitiate / run

  rect rgba(0,128,0,0.5)
  CLI->>WithTelemetry: invoke withTelemetry(options)
  end

  opt Telemetry not resolved
    WithTelemetry->>WithTelemetry: resolveTelemetryState(options)
    alt CLI provides disableTelemetry
      WithTelemetry->>Telemetry: setTelemetryEnabled(!options.disableTelemetry)
    else CLI no explicit value
      WithTelemetry->>Config: loadMainConfig({ configDir: '.storybook' })
      alt config loads
        Config-->>WithTelemetry: mainConfig
        WithTelemetry->>Telemetry: setTelemetryEnabled(!mainConfig.core?.disableTelemetry)
      else config fails
        WithTelemetry->>Telemetry: setTelemetryEnabled(fallbackTelemetryState)
      end
    end
  end

  WithTelemetry->>Runner: proceed to doInitiate / run()
  Runner->>Telemetry: emit events (e.g., "init", "build", "version-update")
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Review rate limit: 4/5 reviews remaining, refill in 12 minutes.

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@code/lib/create-storybook/src/initiate.ts`:
- Line 210: The call setTelemetryEnabled(!options.disableTelemetry) is
prematurely forcing telemetry state before withTelemetry/doInitiate can resolve
config-based settings; remove this call (or change it to consult
tryResolveTelemetryStateFromConfig) so telemetry state is resolved inside
withTelemetry/doInitiate instead—locate and remove the setTelemetryEnabled
invocation in initiate.ts (the code around doInitiate, withTelemetry,
tryResolveTelemetryStateFromConfig and options.disableTelemetry) so config
(core.disableTelemetry) can correctly override CLI defaults.
- Around line 209-210: The call to the async function
setTelemetryEnabled(!options.disableTelemetry) is a floating Promise and must
handle rejections; keep it non-blocking but attach a .catch to swallow/log any
error (e.g., setTelemetryEnabled(!options.disableTelemetry).catch(err => { /*
log or warn */ })), ensuring you use the existing logger or console to surface
the error, and leave it before the init flow so it remains non-blocking; update
the code around the setTelemetryEnabled call to include this .catch handler.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: eb7c597f-0408-4fa7-baaf-90a72efa8950

📥 Commits

Reviewing files that changed from the base of the PR and between b516e85 and 31fd3ef.

📒 Files selected for processing (1)
  • code/lib/create-storybook/src/initiate.ts

Comment thread code/lib/create-storybook/src/initiate.ts Outdated
Comment thread code/lib/create-storybook/src/initiate.ts Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
code/lib/create-storybook/src/initiate.ts (1)

211-213: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Do not override telemetry state after withTelemetry has already resolved it.

On Line 212, this second setTelemetryEnabled call can re-enable telemetry after withTelemetry has resolved a config-based opt-out (from core.disableTelemetry). It effectively bypasses the resolution done before run().

Proposed fix
-import { telemetry, setTelemetryEnabled } from 'storybook/internal/telemetry';
+import { telemetry } from 'storybook/internal/telemetry';
@@
-      // we need to explicitly set this before init to not delay the events until the end of the flow
-      await setTelemetryEnabled(!options.disableTelemetry);
-
       const result = await doInitiate(options);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@code/lib/create-storybook/src/initiate.ts` around lines 211 - 213, The extra
call to setTelemetryEnabled(!options.disableTelemetry) can override the
telemetry decision already made by withTelemetry/core.disableTelemetry; remove
or guard this call so it doesn't re-enable telemetry after withTelemetry has
resolved. Specifically, in initiate.ts remove the unconditional await
setTelemetryEnabled(!options.disableTelemetry) (or change it to only call
setTelemetryEnabled with the resolved value from withTelemetry/run) and ensure
the code uses the telemetry state returned by withTelemetry/run instead of
options.disableTelemetry.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@code/lib/create-storybook/src/initiate.ts`:
- Around line 211-213: The extra call to
setTelemetryEnabled(!options.disableTelemetry) can override the telemetry
decision already made by withTelemetry/core.disableTelemetry; remove or guard
this call so it doesn't re-enable telemetry after withTelemetry has resolved.
Specifically, in initiate.ts remove the unconditional await
setTelemetryEnabled(!options.disableTelemetry) (or change it to only call
setTelemetryEnabled with the resolved value from withTelemetry/run) and ensure
the code uses the telemetry state returned by withTelemetry/run instead of
options.disableTelemetry.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e6e56f25-55cd-453b-a82b-a0203e8d4308

📥 Commits

Reviewing files that changed from the base of the PR and between 722b7a4 and a812637.

📒 Files selected for processing (6)
  • code/core/src/core-server/build-dev.ts
  • code/core/src/core-server/build-static.ts
  • code/core/src/core-server/presets/common-preset.ts
  • code/core/src/core-server/withTelemetry.test.ts
  • code/core/src/core-server/withTelemetry.ts
  • code/lib/create-storybook/src/initiate.ts

const configDir = options.cliOptions.configDir || options.presetOptions?.configDir;
async function resolveTelemetryState(options: TelemetryOptions) {
// 1. If telemetry is explicitly set via CLI options or env var, set and skip loading main config
if (options.cliOptions.disableTelemetry !== undefined) {
Copy link
Copy Markdown
Member

@yannbf yannbf May 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this account for the environment variable as well? should it? (in case resolving main.js fails in the next step)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it does (the comment even say that 😆)
"CLI options" immediately fallback to env vars too, when they are collected at the very beginning

@JReinhold JReinhold merged commit e0791c3 into next May 1, 2026
125 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants