{"id":"f412b113a994de38","repo":"redis/node-redis","slug":"otelmetrics-already-initialized","errorCode":null,"errorMessage":"OTelMetrics already initialized","messagePattern":"OTelMetrics already initialized","errorType":"exception","errorClass":"OpenTelemetryError","httpStatus":null,"severity":"error","filePath":"packages/client/lib/opentelemetry/metrics.ts","lineNumber":544,"sourceCode":"      this.commandMetrics = { destroy() {} };\n    }\n\n    this.#channelSubscribers = new OTelChannelSubscribers(\n      this.#options,\n      this.#instruments,\n      this.#options.enabledMetricGroups,\n    );\n  }\n\n  public static init({\n    api,\n    config,\n  }: {\n    api: OpenTelemetryApiModule;\n    config?: ObservabilityConfig;\n  }) {\n    if (OTelMetrics.#initialized) {\n      throw new OpenTelemetryError(\"OTelMetrics already initialized\");\n    }\n    const instance = new OTelMetrics(api, config);\n    OTelMetrics.#instance = instance;\n    OTelMetrics.#initialized = true;\n  }\n\n  /**\n   * Reset the instance to noop. Used for testing.\n   *\n   * @internal\n   */\n  public static reset() {\n    if (!OTelMetrics.#initialized) return;\n    OTelMetrics.#instance.commandMetrics.destroy();\n    OTelMetrics.#instance.#channelSubscribers.destroy();\n    OTelMetrics.#initialized = false;\n  }\n","sourceCodeStart":526,"sourceCodeEnd":562,"githubUrl":"https://github.com/redis/node-redis/blob/bb5beb56578573910e2ee8f39681edc214c41398/packages/client/lib/opentelemetry/metrics.ts#L526-L562","documentation":"OTelMetrics is itself a singleton guarded by a static #initialized flag; OTelMetrics.init() throws OpenTelemetryError if called twice. In practice this is invoked from OpenTelemetry.init(), so the user-facing cause is the same as the OpenTelemetry singleton error — repeated initialization of the metrics subsystem.","triggerScenarios":"Directly calling OTelMetrics.init() more than once, or calling OpenTelemetry.init() twice (which delegates here). Also reachable in test setups that call OTelMetrics.init without OTelMetrics.reset() between cases.","commonSituations":"Test suites repeatedly initializing metrics; HMR/watch reload re-running bootstrap; a library and an app both trying to initialize OTel metrics in the same process.","solutions":["Initialize metrics once via OpenTelemetry.init(); do not call OTelMetrics.init() directly.","In tests, call OTelMetrics.reset() before re-initializing.","Guard the init call site with OTelMetrics.isInitialized().","Consolidate bootstrap so only one caller initializes OTel."],"exampleFix":"// before\nOTelMetrics.init({ api, config }); // called per test\n\n// after\nif (!OTelMetrics.isInitialized()) OTelMetrics.init({ api, config });\n// in afterEach: OTelMetrics.reset();","handlingStrategy":"validation","validationCode":"if (!OTelMetrics.isInitialized()) OTelMetrics.init({ api, config });","typeGuard":null,"tryCatchPattern":"try { OTelMetrics.init({ api, config }); } catch (e) { if (!/already initialized/.test(e.message)) throw e; }","preventionTips":["Do not call OTelMetrics.init directly — use OpenTelemetry.init once.","In tests, call OTelMetrics.reset() between cases.","Guard with OTelMetrics.isInitialized()."],"tags":["opentelemetry","metrics","singleton","initialization"],"analyzedSha":"bb5beb56578573910e2ee8f39681edc214c41398","analyzedAt":"2026-08-03T19:09:15.686Z","schemaVersion":2}