From 2afcab375cf481cfb88703bdd8fbf82676f2334a Mon Sep 17 00:00:00 2001 From: CG-5228 Date: Wed, 4 Nov 2026 12:27:40 +0000 Subject: [PATCH] fix(api): disable mongoose autoCreate in check-alerts worker --- .changeset/disable-check-alerts-autocreate.md | 5 ++++ .../providers/__tests__/default.test.ts | 27 +++++++++++++++++++ .../tasks/checkAlerts/providers/default.ts | 15 ++++++----- 3 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 .changeset/disable-check-alerts-autocreate.md create mode 100644 packages/api/src/tasks/checkAlerts/providers/__tests__/default.test.ts diff --git a/.changeset/disable-check-alerts-autocreate.md b/.changeset/disable-check-alerts-autocreate.md new file mode 100644 index 0000000000..04e4cbbaed --- /dev/null +++ b/.changeset/disable-check-alerts-autocreate.md @@ -0,0 +1,5 @@ +--- +"@hyperdx/api": patch +--- + +Disable mongoose autoCreate in check-alerts worker to prevent NamespaceExists error spans on mongodb.create diff --git a/packages/api/src/tasks/checkAlerts/providers/__tests__/default.test.ts b/packages/api/src/tasks/checkAlerts/providers/__tests__/default.test.ts new file mode 100644 index 0000000000..0e3047aff2 --- /dev/null +++ b/packages/api/src/tasks/checkAlerts/providers/__tests__/default.test.ts @@ -0,0 +1,27 @@ +import * as models from '@/models'; +import DefaultAlertProvider from '@/tasks/checkAlerts/providers/default'; + +jest.mock('@/models', () => ({ + ...jest.requireActual('@/models'), + connectDB: jest.fn().mockResolvedValue(undefined), + mongooseConnection: { + close: jest.fn().mockResolvedValue(undefined), + }, +})); + +describe('DefaultAlertProvider.init', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('disables both autoIndex and autoCreate when connecting to MongoDB', async () => { + const provider = new DefaultAlertProvider(); + await provider.init(); + + expect(models.connectDB).toHaveBeenCalledTimes(1); + expect(models.connectDB).toHaveBeenCalledWith({ + autoIndex: false, + autoCreate: false, + }); + }); +}); diff --git a/packages/api/src/tasks/checkAlerts/providers/default.ts b/packages/api/src/tasks/checkAlerts/providers/default.ts index b409fafe98..6b02b0898f 100644 --- a/packages/api/src/tasks/checkAlerts/providers/default.ts +++ b/packages/api/src/tasks/checkAlerts/providers/default.ts @@ -409,12 +409,15 @@ async function loadAlert( export default class DefaultAlertProvider implements AlertProvider { async init() { - // The check-alerts worker only reads from MongoDB and never needs to - // ensure indexes exist (the API service owns that). Disabling autoIndex - // prevents background createIndexes calls from racing the short-lived - // connection close (which sends endSessions), surfaced as - // MongoExpiredSessionError on mongodb.createIndexes spans. - await Promise.all([connectDB({ autoIndex: false })]); + // The check-alerts worker only reads/writes existing collections in MongoDB + // and never needs to ensure indexes or collections exist (the API service + // owns the schema). Disabling autoIndex prevents background createIndexes + // calls from racing the short-lived connection close (which sends + // endSessions), surfaced as MongoExpiredSessionError on + // mongodb.createIndexes spans. Disabling autoCreate prevents Model.init() + // from calling createCollection for each model on every run, which + // otherwise records failed mongodb.create (NamespaceExists) spans. + await Promise.all([connectDB({ autoIndex: false, autoCreate: false })]); } async asyncDispose() {