redis/node-redis · error · OpenTelemetryError

OpenTelemetry already initialized

Error message

OpenTelemetry already initialized

What it means

OpenTelemetry is a singleton: OpenTelemetry.init() bootstraps the ClientRegistry and OTelMetrics once for the whole process. Calling init() a second time throws OpenTelemetryError because re-initializing would double-register diagnostics_channel subscribers and meter instruments, corrupting metrics.

Source

Thrown at packages/client/lib/opentelemetry/index.ts:57

   *   exporter: new ConsoleMetricExporter()
   * });
   *
   * const provider = new MeterProvider({ readers: [reader] });
   * metrics.setGlobalMeterProvider(provider);
   *
   * OpenTelemetry.init({
   *   metrics: {
   *     enabled: true,
   *     enabledMetricGroups: ["pubsub", "connection-basic", "resiliency"],
   *     includeCommands: ["GET", "SET"],
   *     hidePubSubChannelNames: true
   *   }
   * });
   * ```
   */
  public static init(config: ObservabilityConfig) {
    if (OpenTelemetry._instance) {
      throw new OpenTelemetryError("OpenTelemetry already initialized");
    }

    const api: OpenTelemetryApiModule = (() => {
      try {
        return require("@opentelemetry/api");
      } catch {
        throw new OpenTelemetryError("@opentelemetry/api not found");
      }
    })();

    OpenTelemetry._instance = new OpenTelemetry();
    ClientRegistry.init();
    OTelMetrics.init({ api, config });
  }
}

export {
  OTelClientAttributes,

View on GitHub (pinned to bb5beb5657)

Solutions

  1. Call OpenTelemetry.init() exactly once at process startup, guarded by a flag or the singleton check.
  2. In tests, reset via OTelMetrics.reset() / module re-import discipline instead of calling init again.
  3. If using HMR/watch, ensure the init call site is not re-executed on reload (move to a module evaluated once).
  4. Guard with a check before calling: only init when not already initialized.

Example fix

// before
OpenTelemetry.init(config); // called in two places

// after
let otelStarted = false;
if (!otelStarted) { OpenTelemetry.init(config); otelStarted = true; }
Defensive patterns

Strategy: validation

Validate before calling

let _otelInit = false;
if (!_otelInit) { OpenTelemetry.init(config); _otelInit = true; }

Try / catch

try { OpenTelemetry.init(config); } catch (e) { if (!/already initialized/.test(e.message)) throw e; }

Prevention

When it happens

Trigger: Calling OpenTelemetry.init(config) more than once in the same process; calling it again after a hot reload (HMR, tsx watch, jest resetModules without reset); init invoked in both a framework bootstrap and an app bootstrap.

Common situations: Multiple entry points (worker + server) sharing a process; test suites that re-import the redis module; dev servers with watch-mode reload that re-execute init; accidental double init in bootstrap ordering.

Related errors


AI-assisted analysis of redis/node-redis@bb5beb5657 (2026-08-03). Data as JSON: /data/errors/c0ed4e17ab3eca9e.json. Report an issue: GitHub.