Compare commits

...

2 Commits

Author SHA1 Message Date
dante01yoon
e746136e14 fix: skip broken subgraph links in graphToPrompt instead of crashing
Catch InvalidLinkError during input resolution so workflows with
stale or broken link references can still be converted to API
format. The broken input is silently skipped rather than aborting
the entire conversion.
2026-04-04 14:18:53 +09:00
dante01yoon
6c2df39d5f test: add failing test for broken subgraph links crashing graphToPrompt
Workflows with stale link IDs in subgraph node data cause
graphToPrompt to throw InvalidLinkError, preventing execution
entirely. The conversion should skip broken inputs gracefully.
2026-04-04 14:16:11 +09:00
2 changed files with 53 additions and 1 deletions

View File

@@ -0,0 +1,45 @@
import { createTestingPinia } from '@pinia/testing'
import { setActivePinia } from 'pinia'
import { beforeEach, describe, expect, it } from 'vitest'
import { LGraph, LGraphNode, LiteGraph } from '@/lib/litegraph/src/litegraph'
import { graphToPrompt } from './executionUtil'
beforeEach(() => {
setActivePinia(createTestingPinia({ stubActions: false }))
})
describe('graphToPrompt', () => {
it('skips inputs with broken links instead of crashing', async () => {
LiteGraph.registerNodeType(
'TestSampler',
class extends LGraphNode {
static override title = 'TestSampler'
constructor() {
super('TestSampler')
this.comfyClass = 'TestSampler'
this.addInput('model', 'MODEL')
this.addInput('seed', 'INT')
this.addOutput('output', 'LATENT')
}
}
)
const graph = new LGraph()
const node = LiteGraph.createNode('TestSampler')!
graph.add(node)
// Inject a broken link: input references a link ID that doesn't exist
node.inputs[0].link = 9999
// BUG: graphToPrompt throws InvalidLinkError instead of skipping
// the broken input. Workflows with stale link references should
// still be convertible to API format.
const result = await graphToPrompt(graph)
expect(result.output).toBeDefined()
expect(result.output[String(node.id)]).toBeDefined()
// Broken 'model' input should be skipped, not crash the conversion
expect(result.output[String(node.id)].inputs).not.toHaveProperty('model')
})
})

View File

@@ -7,6 +7,7 @@ import {
ExecutableNodeDTO,
LGraphEventMode
} from '@/lib/litegraph/src/litegraph'
import { InvalidLinkError } from '@/lib/litegraph/src/infrastructure/InvalidLinkError'
import type {
ComfyApiWorkflow,
ComfyWorkflowJSON
@@ -117,7 +118,13 @@ export const graphToPrompt = async (
// Store all node links
for (const [i, input] of node.inputs.entries()) {
const resolvedInput = node.resolveInput(i)
let resolvedInput
try {
resolvedInput = node.resolveInput(i)
} catch (e) {
if (e instanceof InvalidLinkError) continue
throw e
}
if (!resolvedInput) continue
// Resolved to an actual widget value rather than a node connection