jaeone94 1349fffbce Feat/errors tab panel (#8807)
## Summary

Add a dedicated **Errors tab** to the Right Side Panel that displays
prompt-level, node validation, and runtime execution errors in a
unified, searchable, grouped view — replacing the need to rely solely on
modal dialogs for error inspection.

## Changes

- **What**:
  - **New components** (`errors/` directory):
- `TabErrors.vue` — Main error tab with search, grouping by class type,
and canvas navigation (locate node / enter subgraph).
- `ErrorNodeCard.vue` — Renders a single error card with node ID badge,
title, action buttons, and error details.
- `types.ts` — Shared type definitions (`ErrorItem`, `ErrorCardData`,
`ErrorGroup`).
- **`executionStore.ts`** — Added `PromptError` interface,
`lastPromptError` ref and `hasAnyError` computed getter. Clears
`lastPromptError` alongside existing error state on execution start and
graph clear.
- **`rightSidePanelStore.ts`** — Registered `'errors'` as a valid tab
value.
- **`app.ts`** — On prompt submission failure (`PromptExecutionError`),
stores prompt-level errors (when no node errors exist) into
`lastPromptError`. On both runtime execution error and prompt error,
deselects all nodes and opens the errors tab automatically.
- **`RightSidePanel.vue`** — Shows the `'errors'` tab (with ⚠ icon) when
errors exist and no node is selected. Routes to `TabErrors` component.
- **`TopMenuSection.vue`** — Highlights the action bar with a red border
when any error exists, using `hasAnyError`.
- **`SectionWidgets.vue`** — Detects per-node errors by matching
execution IDs to graph node IDs. Shows an error icon (⚠) and "See Error"
button that navigates to the errors tab.
- **`en/main.json`** — Added i18n keys: `errors`, `noErrors`,
`enterSubgraph`, `seeError`, `promptErrors.*`, and `errorHelp*`.
- **Testing**: 6 unit tests (`TabErrors.test.ts`) covering
prompt/node/runtime errors, search filtering, and clipboard copy.
- **Storybook**: 7 stories (`ErrorNodeCard.stories.ts`) for badge
visibility, subgraph buttons, multiple errors, runtime tracebacks, and
prompt-only errors.
- **Breaking**: None
- **Dependencies**: None — uses only existing project dependencies
(`vue-i18n`, `pinia`, `primevue`)

## Related Work

> **Note**: Upstream PR #8603 (`New bottom button and badges`)
introduced a separate `TabError.vue` (singular) that shows per-node
errors when a specific node is selected. Our `TabErrors.vue` (plural)
provides the **global error overview** — a different scope. The two tabs
coexist:
> - `'error'` (singular) → appears when a node with errors is selected →
shows only that node's errors
> - `'errors'` (plural) → appears when no node is selected and errors
exist → shows all errors grouped by class type
>
> A future consolidation of these two tabs may be desirable after design
review.

## Architecture

```
executionStore
├── lastPromptError: PromptError | null     ← NEW (prompt-level errors without node IDs)
├── lastNodeErrors: Record<string, NodeError>  (existing)
├── lastExecutionError: ExecutionError         (existing)
└── hasAnyError: ComputedRef<boolean>       ← NEW (centralized error detection)

TabErrors.vue (errors tab - global view)
├── errorGroups: ComputedRef<ErrorGroup[]>  ← normalizes all 3 error sources
├── filteredGroups                          ← search-filtered view
├── locateNode()                            ← pan canvas to node
├── enterSubgraph()                         ← navigate into subgraph
└── ErrorNodeCard.vue                       ← per-node card with copy/locate actions

types.ts
├── ErrorItem      { message, details?, isRuntimeError? }
├── ErrorCardData  { id, title, nodeId?, errors[] }
└── ErrorGroup     { title, cards[], priority }
```

## Review Focus

1. **Error normalization logic** (`TabErrors.vue` L75–150): Three
different error sources (prompt, node validation, runtime) are
normalized into a common `ErrorGroup → ErrorCardData → ErrorItem`
hierarchy. Edge cases to verify:
- Prompt errors with known vs unknown types (known types use localized
descriptions)
   - Multiple errors on the same node (grouped into one card)
   - Runtime errors with long tracebacks (capped height with scroll)

2. **Canvas navigation** (`TabErrors.vue` L210–250): The `locateNode`
and `enterSubgraph` functions navigate to potentially nested subgraphs.
The double `requestAnimationFrame` is required due to LiteGraph's
asynchronous subgraph switching — worth verifying this timing is
sufficient.

3. **Store getter consolidation**: `hasAnyError` replaces duplicated
logic in `TopMenuSection` and `RightSidePanel`. Confirm that the
reactive dependency chain works correctly (it depends on 3 separate
refs).

4. **Coexistence with upstream `TabError.vue`**: The singular `'error'`
tab (upstream, PR #8603) and our plural `'errors'` tab serve different
purposes but share similar naming. Consider whether a unified approach
is preferred.

## Test Results

```
✓ renders "no errors" state when store is empty
✓ renders prompt-level errors (Group title = error message)
✓ renders node validation errors grouped by class_type
✓ renders runtime execution errors from WebSocket
✓ filters errors based on search query
✓ calls copyToClipboard when copy button is clicked

Test Files  1 passed (1)
     Tests  6 passed (6)
```

## Screenshots (if applicable)
<img width="1238" height="1914" alt="image"
src="https://github.com/user-attachments/assets/ec39b872-cca1-4076-8795-8bc7c05dc665"
/>
<img width="669" height="1028" alt="image"
src="https://github.com/user-attachments/assets/bdcaa82a-34b0-46a5-a08f-14950c5a479b"
/>
<img width="644" height="1005" alt="image"
src="https://github.com/user-attachments/assets/ffef38c6-8f42-4c01-a0de-11709d54b638"
/>
<img width="672" height="505" alt="image"
src="https://github.com/user-attachments/assets/5cff7f57-8d79-4808-a71e-9ad05bab6e17"
/>

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8807-Feat-errors-tab-panel-3046d73d36508127981ac670a70da467)
by [Unito](https://www.unito.io)
2026-02-17 21:01:15 -08:00
2026-02-16 10:06:15 -08:00
2026-02-17 21:01:15 -08:00
2026-02-06 20:52:53 -08:00
2026-02-12 00:13:48 +01:00
2024-06-12 20:22:24 -04:00
2025-08-27 23:11:03 -07:00
2026-02-17 02:22:09 -08:00
2026-02-10 22:42:26 -08:00
2026-02-10 22:42:26 -08:00
2026-01-27 17:59:19 -08:00

ComfyUI_frontend

Official front-end implementation of ComfyUI.

Website Discord Matrix

Release Schedule

The project follows a structured release process for each minor version, consisting of three distinct phases:

  1. Development Phase - 2 weeks

    • Active development of new features
    • Code changes merged to the development branch
  2. Feature Freeze - 2 weeks

    • No new features accepted
    • Only bug fixes are cherry-picked to the release branch
    • Testing and stabilization of the codebase
  3. Publication

    • Release is published at the end of the freeze period
    • Version is finalized and made available to all users

Nightly Releases

Nightly releases are published daily at https://github.com/Comfy-Org/ComfyUI_frontend/releases.

To use the latest nightly release, add the following command line argument to your ComfyUI launch script:

--front-end-version Comfy-Org/ComfyUI_frontend@latest

Overlapping Release Cycles

The development of successive minor versions overlaps. For example, while version 1.1 is in feature freeze, development for version 1.2 begins simultaneously. Each feature has approximately 4 weeks from merge to ComfyUI stable release (2 weeks on main, 2 weeks frozen on RC).

Example Release Cycle

Week Date Range Version 1.1 Version 1.2 Version 1.3 Patch Releases
1-2 Mar 1-14 Development - - -
3-4 Mar 15-28 Feature Freeze Development - 1.1.0 through 1.1.13 (daily)
5-6 Mar 29-Apr 11 Released Feature Freeze Development 1.1.14+ (daily)
1.2.0 through 1.2.13 (daily)
7-8 Apr 12-25 - Released Feature Freeze 1.2.14+ (daily)
1.3.0 through 1.3.13 (daily)

Release Summary

Major features

v1.5: Native translation (i18n)

ComfyUI now includes built-in translation support, replacing the need for third-party translation extensions. Select your language in Comfy > Locale > Language to translate the interface into English, Chinese (Simplified), Russian, Japanese, Korean, or Arabic. This native implementation offers better performance, reliability, and maintainability compared to previous solutions.

More details available here: https://blog.comfy.org/p/native-localization-support-i18n

v1.4: New mask editor

https://github.com/Comfy-Org/ComfyUI_frontend/pull/1284 implements a new mask editor.

image

v1.3.22: Integrated server terminal

Press Ctrl + ` to toggle integrated terminal.

https://github.com/user-attachments/assets/eddedc6a-07a3-4a83-9475-63b3977f6d94

v1.3.7: Keybinding customization

Basic UI

image

Reset button

image

Edit Keybinding

image image

rec.webm

v1.2.4: Node library sidebar tab

Drag & Drop

https://github.com/user-attachments/assets/853e20b7-bc0e-49c9-bbce-a2ba7566f92f

Filter

https://github.com/user-attachments/assets/4bbca3ee-318f-4cf0-be32-a5a5541066cf

v1.2.0: Queue/History sidebar tab

https://github.com/user-attachments/assets/86e264fe-4d26-4f07-aa9a-83bdd2d02b8f

QoL changes

v1.3.32: **Litegraph** Nested group

https://github.com/user-attachments/assets/f51adeb1-028e-40af-81e4-0ac13075198a

v1.3.24: **Litegraph** Group selection

https://github.com/user-attachments/assets/e6230a94-411e-4fba-90cb-6c694200adaa

v1.3.4: **Litegraph** Auto widget to input conversion

Dropping a link of correct type on node widget will automatically convert the widget to input.

rec.webm

v1.3.4: **Litegraph** Canvas pan mode

The canvas becomes readonly in pan mode. Pan mode is activated by clicking the pan mode button on the canvas menu or by holding the space key.

rec.webm

v1.2.62: **Litegraph** Show optional input slots as donuts

GYEIRidb0AYGO-v

v1.2.44: **Litegraph** Double click group title to edit

https://github.com/user-attachments/assets/5bf0e2b6-8b3a-40a7-b44f-f0879e9ad26f

v1.2.39: **Litegraph** Group selected nodes with Ctrl + G

https://github.com/user-attachments/assets/7805dc54-0854-4a28-8bcd-4b007fa01151

v1.2.38: **Litegraph** Double click node title to edit

https://github.com/user-attachments/assets/d61d5d0e-f200-4153-b293-3e3f6a212b30

v1.1.8: **Litegraph** hides text overflow on widget value

https://github.com/user-attachments/assets/5696a89d-4a47-4fcc-9e8c-71e1264943f2

Developer APIs

v1.6.13: prompt/confirm/alert replacements for ComfyUI desktop

Several browser-only APIs are not available in ComfyUI desktop's electron environment.

  • window.prompt
  • window.confirm
  • window.alert

Please use the following APIs as replacements.

// window.prompt
window['app'].extensionManager.dialog
  .prompt({
    title: 'Test Prompt',
    message: 'Test Prompt Message'
  })
  .then((value: string) => {
    // Do something with the value user entered
  })

image

// window.confirm
window['app'].extensionManager.dialog
  .confirm({
    title: 'Test Confirm',
    message: 'Test Confirm Message'
  })
  .then((value: boolean) => {
    // Do something with the value user entered
  })

image

// window.alert
window['app'].extensionManager.toast.addAlert('Test Alert')

image

v1.3.34: Register about panel badges
app.registerExtension({
  name: 'TestExtension1',
  aboutPageBadges: [
    {
      label: 'Test Badge',
      url: 'https://example.com',
      icon: 'pi pi-box'
    }
  ]
})

image

v1.3.22: Register bottom panel tabs
app.registerExtension({
  name: 'TestExtension',
  bottomPanelTabs: [
    {
      id: 'TestTab',
      title: 'Test Tab',
      type: 'custom',
      render: (el) => {
        el.innerHTML = '<div>Custom tab</div>'
      }
    }
  ]
})

image

v1.3.22: New settings API

Legacy settings API.

// Register a new setting
app.ui.settings.addSetting({
  id: 'TestSetting',
  name: 'Test Setting',
  type: 'text',
  defaultValue: 'Hello, world!'
})

// Get the value of a setting
const value = app.ui.settings.getSettingValue('TestSetting')

// Set the value of a setting
app.ui.settings.setSettingValue('TestSetting', 'Hello, universe!')

New settings API.

// Register a new setting
app.registerExtension({
  name: 'TestExtension1',
  settings: [
    {
      id: 'TestSetting',
      name: 'Test Setting',
      type: 'text',
      defaultValue: 'Hello, world!'
    }
  ]
})

// Get the value of a setting
const value = app.extensionManager.setting.get('TestSetting')

// Set the value of a setting
app.extensionManager.setting.set('TestSetting', 'Hello, universe!')
v1.3.7: Register commands and keybindings

Extensions can call the following API to register commands and keybindings. Do note that keybindings defined in core cannot be overwritten, and some keybindings are reserved by the browser.

app.registerExtension({
  name: 'TestExtension1',
  commands: [
    {
      id: 'TestCommand',
      function: () => {
        alert('TestCommand')
      }
    }
  ],
  keybindings: [
    {
      combo: { key: 'k' },
      commandId: 'TestCommand'
    }
  ]
})
v1.3.1: Extension API to register custom topbar menu items

Extensions can call the following API to register custom topbar menu items.

app.registerExtension({
  name: 'TestExtension1',
  commands: [
    {
      id: 'foo-id',
      label: 'foo',
      function: () => {
        alert(1)
      }
    }
  ],
  menuCommands: [
    {
      path: ['ext', 'ext2'],
      commands: ['foo-id']
    }
  ]
})

image

v1.2.27: Extension API to add toast messagei

Extensions can call the following API to add toast messages.

app.extensionManager.toast.add({
  severity: 'info',
  summary: 'Loaded!',
  detail: 'Extension loaded!',
  life: 3000
})

Documentation of all supported options can be found here: https://primevue.org/toast/#api.toast.interfaces.ToastMessageOptions

image

v1.2.4: Extension API to register custom sidebar tab

Extensions now can call the following API to register a sidebar tab.

app.extensionManager.registerSidebarTab({
  id: 'search',
  icon: 'pi pi-search',
  title: 'search',
  tooltip: 'search',
  type: 'custom',
  render: (el) => {
    el.innerHTML = '<div>Custom search tab</div>'
  }
})

The list of supported icons can be found here: https://primevue.org/icons/#list

We will support custom icons later.

image

v1.10.9: Selection Toolbox API

Extensions can register commands that appear in the selection toolbox when specific items are selected on the canvas.

app.registerExtension({
  name: 'TestExtension1',
  commands: [
    {
      id: 'test.selection.command',
      label: 'Test Command',
      icon: 'pi pi-star',
      function: () => {
        // Command logic here
      }
    }
  ],
  // Return an array of command IDs to show in the selection toolbox
  // when an item is selected
  getSelectionToolboxCommands: (selectedItem) => ['test.selection.command']
})

The selection toolbox will display the command button when items are selected: Image

Contributing

We welcome contributions to ComfyUI Frontend! Please see our Contributing Guide for:

  • Ways to contribute (code, documentation, testing, community support)
  • Development setup and workflow
  • Code style guidelines
  • Testing requirements
  • How to submit pull requests
  • Backporting fixes to release branches

Development

For detailed development setup, testing procedures, and technical information, please refer to CONTRIBUTING.md.

i18n

See locales/README.md for details.

Storybook

See .storybook/README.md for component development and visual testing documentation.

Troubleshooting

For comprehensive troubleshooting and technical support, please refer to our official documentation:

Description
Official front-end implementation of ComfyUI
Readme GPL-3.0 730 MiB
Languages
TypeScript 80.2%
Vue 18.4%
CSS 0.7%
Python 0.3%
Shell 0.2%
Other 0.2%