Skip to content

fix(tools): invoke tool reset methods on destroy - #3046

Merged
neSpecc merged 2 commits into
codex-team:nextfrom
prajexec:fix/tools-destroy-reset
Nov 14, 2026
Merged

neSpecc merged 2 commits into
codex-team:nextfrom
prajexec:fix/tools-destroy-reset

Conversation

@prajexec

Copy link
Copy Markdown
Contributor

Description

Bug

In src/components/modules/tools.ts, Tools.destroy() invoked Object.values(this.available).forEach(...). Since this.available is an instance of ToolsCollection (which extends Map), Object.values() returns an empty array []. As a result, tool.reset() was never actually executed on any available tool when destroying the editor instance.

Fix

Replaced Object.values(this.available) with Array.from(this.available.values()) so that each tool's reset() method is properly invoked during destroy.

Test

Added a test spec in test/cypress/tests/modules/Tools.cy.ts (context('.destroy()')) verifying that reset() is called on registered tools when the module is destroyed.

  • Fails without this fix: "expected stub to have been called exactly once, but it was never called" (21 passing, 1 failing).
  • Passes with this fix: 22 passing.

Behavior Note

Because of the bug, tool.reset() has effectively never run on destroy until now. None of the default built-in tools currently implement a reset() method, but third-party tools defining a static reset() will now have it executed during teardown as originally intended.

Open Question for Maintainers

The loop currently runs as:

Array.from(this.available.values()).forEach(async (tool) => {
  if (isFunction(tool.reset)) {
    await tool.reset();
  }
});

Because forEach(async ...) does not await or collect returned promises, if a tool's async reset() rejects, it becomes an unhandled promise rejection.

  • Would you prefer adding a .catch(...) with a warning log directly in this PR?
  • Or keep this PR strictly minimal and address async lifecycle error handling in a broader follow-up?

@neSpecc

neSpecc commented Nov 14, 2026

Copy link
Copy Markdown
Member

Would you prefer adding a .catch(...) with a warning log directly in this PR?

this sounds ok

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approved

No active review issues were identified for the tool-teardown cleanup fix.

No open issues 🎉

What changed in this PR

Fixes tool cleanup during editor teardown by correctly iterating the Map-backed tool collection, allowing registered tools’ reset() methods to run.

Changes:

  • Invokes available tools’ reset methods and catches failures, logging them as warnings.
  • Adds regression tests for reset invocation and rejected-reset warning handling.
  • Documents the teardown fix in the changelog.
File Description
test/​cypress/​tests/​modules/​Tools.cy.ts Tests reset invocation and warning logging when reset rejects.
src/​components/​modules/​tools.ts Corrects collection iteration and adds reset error handling.
docs/​CHANGELOG.md Records the reset invocation and error-handling fix.

Review effort: Balanced

@neSpecc
neSpecc merged commit 7d52d62 into codex-team:next Nov 14, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants