Skip to content

[BUG] 3.4.x: XHR (Ajax) instrumentation never installs when bundled as ESM (Vite/Rollup) - no dependency telemetry and no traceparent #2760

Description

Description/Screenshot

Starting with 3.4.1, the SDK's XHR (Ajax) instrumentation never installs when the SDK is bundled as ESM by Vite/Rollup. XMLHttpRequest.prototype.open and .send remain native, so:

  • no RemoteDependencyData is emitted for XHR calls, and
  • no correlation headers (traceparent / Request-Id) are attached to XHR requests, which silently breaks browser → server distributed tracing.

The failure is completely silent. There is no error, no internal-log entry, and the plugin reports itself as healthy:

  • appInsights.core.isInitialized()true
  • appInsights.core.getPlugin('AjaxDependencyPlugin') → returns the plugin
  • XMLHttpRequest.prototype.open.toString()"function open() { [native code] }" ← never hooked

fetch instrumentation in the same build is unaffected — with disableFetchTracking unset, window.fetch is patched and fetch() calls do emit RemoteDependencyData. So only the XHR path is broken, which makes this easy to miss: pageViews, exceptions, traces and browserTimings all keep working and only dependencies disappear.

The same version works correctly when loaded via the UMD/global bundle, which suggests a bundling/packaging issue rather than a logic bug.

Steps to Reproduce

  • OS/Browser: Windows 11 / Chrome 151 (also reproduces headless via Playwright)
  • SDK Version: 3.4.1 and 3.4.3 reproduce; 3.3.9 and 3.3.11 do not
  • How you initialized the SDK: npm package, ESM import, bundled with Vite 5 (vite build), plain new ApplicationInsights({config}) + loadAppInsights() — no framework extensions required

Minimal repro (~30 lines, no framework):

package.json

{
  "name": "ai-xhr-hook-repro",
  "private": true,
  "type": "module",
  "devDependencies": { "vite": "^5.4.21" },
  "dependencies": { "@microsoft/applicationinsights-web": "3.4.3" }
}

index.html

<!doctype html>
<html><head><meta charset="utf-8"></head>
<body><pre id="out"></pre><script type="module" src="./main.js"></script></body></html>

main.js

import { ApplicationInsights } from '@microsoft/applicationinsights-web';

const ai = new ApplicationInsights({
  config: {
    connectionString:
      'InstrumentationKey=00000000-0000-0000-0000-000000000000;IngestionEndpoint=http://127.0.0.1:9/',
    enableAutoRouteTracking: true,
  },
});
ai.loadAppInsights();

window.__items = [];
ai.addTelemetryInitializer((e) => { window.__items.push(e.baseType); return false; }); // capture, don't send

const isNative = (s) => /\{\s*\[native code\]\s*\}/.test(String(s));

window.__run = () => new Promise((resolve) => {
  setTimeout(() => {                       // allow async plugin init to settle
    const probe = {
      xhrOpenIsNative: isNative(XMLHttpRequest.prototype.open),
      fetchIsNative: isNative(window.fetch),
      coreInitialized: ai.core.isInitialized(),
      ajaxPluginRegistered: !!ai.core.getPlugin('AjaxDependencyPlugin'),
    };
    const before = window.__items.length;
    const x = new XMLHttpRequest();
    x.open('GET', '/index.html?probe=1', true);
    x.onloadend = () => setTimeout(
      () => resolve({ ...probe, depsEmitted: window.__items.length - before }), 600);
    x.send();
  }, 1500);
});

Then:

npm install
npx vite build
npx http-server dist -p 8080     # or any static server
# open http://127.0.0.1:8080/ and run in the console:
await window.__run()

Expected behavior

XMLHttpRequest.prototype.open is patched, and the XHR emits one RemoteDependencyData item:

{ xhrOpenIsNative: false, depsEmitted: 1, ... }

Actual behavior

The XHR is never instrumented and no dependency is emitted, despite the plugin reporting as registered and the core as initialized:

{ xhrOpenIsNative: true,       // <-- never hooked
  fetchIsNative: false,        // fetch hook installed fine
  coreInitialized: true,
  ajaxPluginRegistered: true,
  depsEmitted: 0 }

Additional context

Result matrix — identical config and identical repro, only the SDK version changed, one version per run:

@microsoft/applicationinsights-web Build XHR hook Deps emitted
3.3.9 ESM + Vite/Rollup installs 1
3.3.11 ESM + Vite/Rollup installs 1
3.4.1 ESM + Vite/Rollup missing 0
3.4.3 ESM + Vite/Rollup missing 0
3.4.1 UMD (ai.3.4.1.gbl.min.js, <script> tag) installs

Notes that may help narrow it down:

  • 3.4.0 does not appear to have been published, so 3.4.1 is the first release of the 3.4.x line and the regression point.
  • 3.4.1 is also the release that refactored the dependencies extension (the ajaxRecord class was removed in favour of IAjaxRecordData) and merged @microsoft/applicationinsights-common into applicationinsights-core-js "to improve tree-shaking". dependencies-js's ajax.js correspondingly changed its imports from applicationinsights-common (3.3.11) to applicationinsights-core-js (3.4.1).
  • The same version working under UMD but not ESM points at packaging/tree-shaking rather than the instrumentation logic itself. _supportsAjaxMonitoring() appears materially unchanged between 3.3.11 and 3.4.1, so the early-return guard inside _instrumentXhr() does not look like the cause.
  • Not caused by a duplicated applicationinsights-common: applicationinsights-web@3.4.3 no longer depends on it at all, and the repro above reproduces on a clean 3.4.x-only dependency graph.
  • disableAjaxTracking is left at its default (false) throughout; explicitly setting it to false makes no difference.

Impact

This silently disables browser → server correlation for any app whose HTTP client uses XMLHttpRequest — which includes axios in a browser, since axios resolves the xhr adapter first (adapter: ['xhr', 'http', 'fetch']). Because the plugin reports as registered and nothing errors, there is no signal that tracing has stopped working; the only reliable check we found is asserting that XMLHttpRequest.prototype.open.toString() does not contain [native code].

We have pinned to 3.3.11 as a workaround. Happy to test a fix or provide more detail.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions