Comfy-Org / Comfy-Org/ComfyUI_frontend
ECS branch: an emptied output slot returns null instead of [], so node.outputs[i].links.length throws for extensions
- Dominant language
- TypeScript
- Stars
- 2k
- Forks
- 699
- Avg merge
- 1d 7h
- Merged PRs (30d)
- 490
Description
`feature/ecs-migration` changes an emptied output from `[]` to `null` on both the serialized and the live side. The live half breaks extension code.
Verified at PR #14246 head `907ca2b1479381eff7a617e656c9002806b5fa15`.
## Serialized side — harmless, but a deliberate change worth confirming
`node/slotUtils.ts`:
```ts
links: ids.length ? ids : null
```
At the merge base this was `links: links ? [...links] : links`, and **both** shapes reached the file: `disconnectOutput(slot, targetNode)` splices and leaves `[]`, `disconnectOutput(slot)` sets `null`. This always writes `null`. The schema accepts both.
## Live side — an extension break
`NodeOutputSlot.links` returns `null` once `legacyLinksPresent` goes false:
```ts
get links(): LinkId[] | null {
warnDeprecated(...)
this.synchronizeLegacyLinks()
return this.legacyLinksPresent ? this.legacyLinksView : null
}
```
and `synchronizeLegacyLinks` sets `legacyLinksPresent = false` when the id list empties. So after the last **per-target** disconnect the getter returns `null` where classic litegraph returned `[]`.
Extension code doing `node.outputs[i].links.length` throws at that point. The idiom is common in link-walking code — `for (const l of node.outputs[i].links ?? [])` is the defensive form, and packs that predate this change have no reason to have written it.
Suggested: preserve `[]` for a targeted removal in both the live compatibility view and serialization, and keep `null` for a full-output disconnect, which is what the merge base did.
Raised originally as a review thread on #14246; filed so the finding does not depend on that thread.
Related: #15620 and #15634 — the same accessor, the write direction.
Contributor guide
Assessment
This issue has not been assessed yet.