Comfy-Org / Comfy-Org/ComfyUI_frontend

Canvas combo stepper arrows jump to the first option on numeric combos

Open Beginner friendly
#14,538 1 comment 1 reaction 0 assignees View on GitHub
area:widgets Potential Bug
Dominant language
TypeScript
Stars
2k
Forks
699
Avg merge
1d 7h
Merged PRs (30d)
490

Description

Found by @christian-byrne while reviewing #14460, split out because it is pre-existing and out of that PR's scope. Verified independently at HEAD.

## What happens

On the LiteGraph canvas, the increment/decrement arrows on a combo widget whose options are numbers (`[6, 8, 10]`) always land on the **first** option instead of stepping.

## Mechanism

`src/lib/litegraph/src/widgets/ComboWidget.ts:113-121`:

```ts
const foundIndex =
typeof values === 'object'
? indexedValues.indexOf(String(this.value)) + delta
: indexedValues.indexOf(this.value) + delta

const index = clamp(foundIndex, 0, indexedValues.length - 1)
```

`typeof [6, 8, 10] === 'object'` is true for arrays, so the stringified branch runs. But `indexedValues` comes from the local `toArray` (`:25`), which is `Array.isArray(values) ? values : Object.keys(values)` — the numeric array passes through **unstringified**. So `indexOf(String(10))` searches for `'10'` in `[6, 8, 10]` and returns `-1` for every numeric option.

`-1` then produces index `0` in both directions: increment gives `-1 + 1 = 0`, decrement gives `-1 - 1 = -2` which `clamp` raises to `0`.

## Why it is reachable rather than dead

`canUseButton` (`:84`) compares raw values **without** `String()`, so the arrows correctly enable for a mid-list numeric value — and then `tryChangeValue` resets to the first option. The two paths disagree about stringification, which is what makes the broken step reachable in the first place.

It reads as a silent no-op only when the value is already the first option.

## Pre-existing

`git blame` at the merge base `2c937310a3` attributes these lines to `ee222c794b7` (2025-04-28). Not introduced or worsened by #14460, which touches only `WidgetSelect.vue`, `WidgetSelectDefault.vue`, `WidgetSelectDropdown.vue` and tests.

## Related

Same root cause family as #14460 — comparing a stringified option list against an un-stringified value. That PR fixed it in the Vue node path; this is the canvas path.

Contributor guide

Open the contributing guide

Research direction

Read src/lib/litegraph/src/widgets/ComboWidget.ts, especially toArray, canUseButton, and lines 113-121 in tryChangeValue. Reproduce the issue with a numeric combo such as [6, 8, 10], then verify that the increment and decrement arrows move through the numeric options rather than resetting to the first option.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
frontend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.