Comfy-Org / Comfy-Org/ComfyUI_frontend

[Bug]: Custom sidebar extensions not properly destroyed when switching tabs

Open
#4,372 0 comments 0 reactions 0 assignees View on GitHub
area:ui developer experience verified bug
Dominant language
TypeScript
Stars
2k
Forks
699
Avg merge
1d 7h
Merged PRs (30d)
490

Description

## Preliminary Checks

- [x] This bug report is for the latest version of ComfyUI frontend
- [x] There are no existing bug reports for this issue
- [x] This issue persists when all custom nodes are disabled

## What is the expected behavior?

When switching between sidebar tabs, custom extensions should have their `destroy()` method called to properly clean up resources, unmount components, and reset state - similar to how Vue components are automatically cleaned up.

## What is the actual behavior?

Custom sidebar extensions are **not** properly destroyed when switching between tabs. The `destroy()` method is only called when:
1. The custom tab is currently active AND the entire sidebar is closed
2. Never called when switching from a custom tab to another tab (built-in or custom)

This causes custom extensions to remain mounted and visible when they should be hidden, leading to UI overlap and resource leaks.

## Steps to reproduce

1. Install a custom sidebar extension (e.g., ComfyUI-React-Extension-Template)
2. Open the custom extension tab in the sidebar
3. Switch to another sidebar tab (Queue, Node Library, etc.)
4. **Expected**: Custom extension should disappear/be destroyed
5. **Actual**: Custom extension remains visible and overlaps with the new tab

## Additional testing showing the inconsistency:
- ✅ **Built-in tabs**: Properly hide when switching (Queue → Node Library works correctly)
- ❌ **Custom → Built-in**: Custom extension remains visible
- ❌ **Custom → Custom**: Both extensions visible simultaneously
- ❌ **Built-in → Custom**: Custom extension shows but built-in doesn't properly hide

## Root Cause Analysis

The issue is in `SideToolbar.vue` and `ExtensionSlot.vue`:

**Current code in SideToolbar.vue:**
```vue


```

**Problem**: When `selectedTab` changes from `tab1` to `tab2`, Vue **updates** the `ExtensionSlot` component props but doesn't **unmount** it. Therefore `onBeforeUnmount` in `ExtensionSlot.vue` is never triggered, and the previous extension's `destroy()` method is never called.

## Proposed Fix

Add a `key` attribute to force Vue to unmount/remount the ExtensionSlot when the extension changes:

```vue


```

This ensures:
1. Old ExtensionSlot is unmounted (triggering `onBeforeUnmount` → `destroy()`)
2. New ExtensionSlot is mounted with fresh state
3. Proper cleanup of custom extension resources

## Debug Logs

Custom extension logging shows:
```
[React Extension] render() called
[React Extension] Registering sidebar tab with ComfyUI
[React Extension] Sidebar tab registered successfully
// ... switching tabs ...
// destroy() is NEVER called unless sidebar is closed while custom tab is active
```

## Environment

- **Frontend Version**: Latest (main branch)
- **Browser**: Multiple browsers affected
- **Custom Extension**: ComfyUI-React-Extension-Template (and affects all custom sidebar extensions)

## Impact

This bug affects all custom sidebar extensions and causes:
- Visual overlap of UI components
- Memory leaks from unclean component unmounting
- Event listeners not being properly removed
- Inconsistent UX compared to built-in tabs

## Related Issues

This may be related to the general sidebar management system and could affect:
- Issue #3635: Secondary sidebar extensions
- Future custom extension development

## Testing

This issue can be reproduced with any custom sidebar extension. The ComfyUI-React-Extension-Template provides a good test case as it demonstrates the expected `render()`/`destroy()` lifecycle pattern.

┆Issue is synchronized with this [Notion page](https://www.notion.so/Issue-4372-Bug-Custom-sidebar-extensions-not-properly-destroyed-when-switching-tabs-2296d73d36508133a781c8b0630729eb) by [Unito](https://www.unito.io)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.