{"record":{"id":"c8f561ff1db82e3e","repo":"mochajs/mocha","slug":"err-mocha-instance-already-running","errorCode":"ERR_MOCHA_INSTANCE_ALREADY_RUNNING","errorMessage":"Cannot dispose while the mocha instance is still running tests.","messagePattern":"Cannot dispose while the mocha instance is still running tests\\.","errorType":"exception","errorClass":"MochaInstanceAlreadyRunningError","httpStatus":null,"severity":"error","filePath":"lib/mocha.cjs","lineNumber":622,"sourceCode":" * @public\n * @see {@link Mocha#dispose}\n * @param {boolean} cleanReferencesAfterRun\n * @return {Mocha} this\n * @chainable\n */\nMocha.prototype.cleanReferencesAfterRun = function (cleanReferencesAfterRun) {\n  this._cleanReferencesAfterRun = cleanReferencesAfterRun !== false;\n  return this;\n};\n\n/**\n * Manually dispose this mocha instance. Mark this instance as `disposed` and unable to run more tests.\n * It also removes function references to tests functions and hooks, so variables trapped in closures can be cleaned by the garbage collector.\n * @public\n */\nMocha.prototype.dispose = function () {\n  if (this._state === mochaStates.RUNNING) {\n    throw createMochaInstanceAlreadyRunningError(\n      \"Cannot dispose while the mocha instance is still running tests.\",\n    );\n  }\n  this.unloadFiles();\n  this._previousRunner && this._previousRunner.dispose();\n  this.suite.dispose();\n  this._state = mochaStates.DISPOSED;\n};\n\n/**\n * Displays full stack trace upon test failure.\n *\n * @public\n * @see [CLI option](../#-full-trace)\n * @param {boolean} [fullTrace=true] - Whether to print full stacktrace upon failure.\n * @return {Mocha} this\n * @chainable\n */","sourceCodeStart":604,"sourceCodeEnd":640,"githubUrl":"https://github.com/mochajs/mocha/blob/6bcbee4fd9a95351cedf0fdcb14c7d696486bc5a/lib/mocha.cjs#L604-L640","documentation":"dispose() permanently marks a Mocha instance as disposed and clears references to test/hook functions so the GC can reclaim closures. Calling it while a run is in progress would tear down state the active runner still needs, so Mocha throws when _state is RUNNING.","triggerScenarios":"Calling mocha.dispose() while mocha.run() (or runAsync()) is still executing and _state === mochaStates.RUNNING.","commonSituations":"Async cleanup code (e.g. process exit handlers, test-file teardown, watch-mode shutdown) that disposes without awaiting run completion; disposing from a hook or reporter callback during the run.","solutions":["Await the run's completion (the promise/exit from run() or runAsync()) before calling dispose()","Move dispose() into a shutdown/after-run path rather than a hook or in-flight callback","Debounce/queue dispose calls so concurrent shutdown logic cannot dispose mid-run"],"exampleFix":"// before\nmocha.runAsync(failures => {});\nmocha.dispose(); // throws if run still in progress\n// after\nconst runner = await mocha.runAsync(failures => {});\nawait runner;\nmocha.dispose(); // safe after run completes","handlingStrategy":"try-catch","validationCode":"// only dispose after run finished\nif (mocha._state !== 'running') {\n  mocha.dispose();\n}","typeGuard":"function isDisposalSafe(mocha) {\n  return mocha._state !== 'running';\n}","tryCatchPattern":"try {\n  mocha.dispose();\n} catch (err) {\n  if (err.code === 'ERR_MOCHA_INSTANCE_ALREADY_RUNNING') {\n    await runPromise; // await completion then retry once\n    mocha.dispose();\n  } else {\n    throw err;\n  }\n}","preventionTips":["Always await run()/runAsync() before dispose()","Never call dispose() from hooks or reporters during a run","Centralize shutdown logic in one after-run path"],"tags":["mocha","instance-lifecycle","async","programmatic-api"],"backgroundTag":"dispose-while-running","analyzedSha":"6bcbee4fd9a95351cedf0fdcb14c7d696486bc5a","analyzedAt":"2026-09-01T03:41:47.182Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}