Skip to content

Cloudflare adds back channel integrations the user removed, when the module loads after  init() #25576

Open

Description

@isaacs

The @sentry/cloudflare/vite plugin adds a snippet to each instrumented module (for example openai, pg). When the module first runs, the snippet stores an integration factory on a global marker and emits orchestrion.module-injected. At init(), Cloudflare adds every factory already stored to the default integrations.

A module can run after init(), for example a driver loaded with a dynamic import() on first use. For that case, packages/cloudflare/src/baseSdk.ts:158 listens for the event and callsclient.addIntegration(factory()). It does not check the user's options, so it ignores each way a user can opt out:

  • integrations: defaults => defaults.filter(i => i.name !== 'OpenAI')
  • defaultIntegrations: false
  • defaultIntegrations: [...], a custom list without the integration

The user gets the integration they removed. For the AI integrations, that can mean prompt and response capture that the user turned off on purpose. Whether it happens depends on module load order, so it is hard to see.

A user instance that the user passed in integrations is safe: addIntegration skips a name that is already installed.

Proposed solution

Apply the same rules to a late factory as init() applies to the defaults. In initWithDefaultIntegrations:

  1. Before the SDK fills in options.defaultIntegrations, save whether the user set it. If the user set it (false or a custom list), the SDK defaults are off, so the handler does not add late integrations.
  2. If options.integrations is a function, pass the late integration through it with core's getIntegrationsToSetup, as the only default. Install the result entry with the same name, if there is one. If the filter removed it, do nothing. Ignore other entries in the result. Those are already installed from init().
  3. If options.integrations is an array, keep today's behavior. An array cannot remove a default, and addIntegration already skips a name the user configured.

Trade-off for step 2: the SDK calls the user's integrations function again, once for each late module. Most of these functions only filter or add to the list. A function with side effects would run them again. Document this on the integrations option for Cloudflare. The other choice is to save, at init(), which integration names the filter removed, but that only covers modules that were already loaded, which is the case that works today.

Tests in packages/cloudflare/test/sdk.test.ts (it already covers the event): each opt-out form above, plus a configured user instance that must stay in place when its module loads later.

Activity

  1. self-assigned this
    on Oct 20, 2026
  2. linear-code commented on Oct 20, 2026

    @linear-code
  3. added 2 commits that reference this issue on Oct 21, 2026
    32cf42b
    c661f9c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions