{"record":{"id":"c0ed4e17ab3eca9e","repo":"redis/node-redis","slug":"opentelemetry-already-initialized","errorCode":null,"errorMessage":"OpenTelemetry already initialized","messagePattern":"OpenTelemetry already initialized","errorType":"exception","errorClass":"OpenTelemetryError","httpStatus":null,"severity":"error","filePath":"packages/client/lib/opentelemetry/index.ts","lineNumber":57,"sourceCode":"   *   exporter: new ConsoleMetricExporter()\n   * });\n   *\n   * const provider = new MeterProvider({ readers: [reader] });\n   * metrics.setGlobalMeterProvider(provider);\n   *\n   * OpenTelemetry.init({\n   *   metrics: {\n   *     enabled: true,\n   *     enabledMetricGroups: [\"pubsub\", \"connection-basic\", \"resiliency\"],\n   *     includeCommands: [\"GET\", \"SET\"],\n   *     hidePubSubChannelNames: true\n   *   }\n   * });\n   * ```\n   */\n  public static init(config: ObservabilityConfig) {\n    if (OpenTelemetry._instance) {\n      throw new OpenTelemetryError(\"OpenTelemetry already initialized\");\n    }\n\n    const api: OpenTelemetryApiModule = (() => {\n      try {\n        return require(\"@opentelemetry/api\");\n      } catch {\n        throw new OpenTelemetryError(\"@opentelemetry/api not found\");\n      }\n    })();\n\n    OpenTelemetry._instance = new OpenTelemetry();\n    ClientRegistry.init();\n    OTelMetrics.init({ api, config });\n  }\n}\n\nexport {\n  OTelClientAttributes,","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/redis/node-redis/blob/90fd0652bc3f2a0a1b2f79fa9096b02a86b0ac58/packages/client/lib/opentelemetry/index.ts#L39-L75","documentation":"OpenTelemetry.init() was called a second time. The OpenTelemetry class is a singleton — once initialized, calling init again throws to prevent duplicate metric registrations and conflicting configurations. The internal _instance field is already set.","triggerScenarios":"Calling OpenTelemetry.init(config) twice in the same process — in tests that re-run setup, in HMR (hot module replacement) scenarios, or when multiple modules both call init.","commonSituations":"Test suites that call init per test without resetting state; Next.js or Vite HMR re-executing the init module; multiple entry points or microservices in the same process both initializing OTel.","solutions":["Call OpenTelemetry.init() exactly once at application startup","Wrap the init call in try-catch to gracefully handle double initialization","In tests, guard with a module-level boolean flag to avoid re-initialization","In HMR environments, skip init on hot reload by checking a global flag"],"exampleFix":"// before\nOpenTelemetry.init(config);\n\n// after\nlet otelInitialized = false;\nif (!otelInitialized) {\n  try {\n    OpenTelemetry.init(config);\n    otelInitialized = true;\n  } catch (e) {\n    // already initialized — safe to ignore\n  }\n}","handlingStrategy":"validation","validationCode":"// Guard init with a module-level flag.\nlet otelInitialized = false;\n\nexport function initOtel(config: ObservabilityConfig): void {\n  if (otelInitialized) return;\n  try {\n    OpenTelemetry.init(config);\n    otelInitialized = true;\n  } catch (e) {\n    if (e instanceof OpenTelemetryError && e.message === 'OpenTelemetry already initialized') {\n      otelInitialized = true;\n      return;\n    }\n    throw e;\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  OpenTelemetry.init(config);\n} catch (e) {\n  if (e instanceof OpenTelemetryError && e.message.includes('already initialized')) {\n    // Safe to ignore — singleton is already set up\n  } else {\n    throw e;\n  }\n}","preventionTips":["Call OpenTelemetry.init() exactly once at process startup","Use a module-level boolean guard in test suites to prevent re-initialization","In HMR environments, check a global flag before calling init","Centralize OTel initialization in a single bootstrap module"],"tags":["opentelemetry","singleton","initialization"],"backgroundTag":null,"analyzedSha":"90fd0652bc3f2a0a1b2f79fa9096b02a86b0ac58","analyzedAt":"2026-08-11T15:37:21.243Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}