Skip to content

Commit b3b180c

Browse files
christian-byrnegithub-actionscoderabbitai[bot]
authored andcommitted
fix: loading api-format workflow that contains "parameters" string (#7411)
## Summary This change extends #7154 by making sure the `prompt` metadata tag is parsed before the legacy A1111 fallback when files are dropped onto the canvas. ComfyUI embeds two structured payloads into every first-class export format we support (PNG, WEBP, WEBM, MP4/MOV/M4V, GLB, SVG, MP3, OGG/FLAC, etc.): `workflow`, which is the full editor JSON with layout state, and `prompt`, which is the API graph sent to `/prompt`. During import we try format-specific decoders first and only as a last resort look for an A1111 file by scanning text chunks for a `parameters` entry. That compatibility path was always meant to be a best-effort option, but when we refactored the loader it accidentally enforced the order `workflow → parameters → prompt`. As soon as a dropped asset contained a `parameters` chunk—something Image Saver’s “A1111 compatibility” mode always adds—the A1111 converter activated and blocked the subsequent `prompt` loading logic. PR #7154 already lifted `workflow` ahead of the fallback, yet any file lacking the `workflow` chunk but holding both `prompt` and `parameters` still regressed. Reordering to `workflow → prompt → parameters` preserves the compatibility shim for genuine A1111 exports while guaranteeing native Comfy metadata always wins, eliminating the entire class of failures triggered merely by the presence of the word `parameters` in an unrelated metadata chunk. Fixes #7096, fixes #6988 ## Related (fixed by #7154) - #6633 - #6561 --------- Co-authored-by: github-actions <[email protected]> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
1 parent 02b3509 commit b3b180c

File tree

4 files changed

+31
-9
lines changed

4 files changed

+31
-9
lines changed
422 Bytes
Loading

browser_tests/tests/loadWorkflowInMedia.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ test.describe('Load Workflow in Media', () => {
1212
'edited_workflow.webp',
1313
'no_workflow.webp',
1414
'large_workflow.webp',
15+
'workflow_prompt_parameters.png',
1516
'workflow.webm',
1617
// Skipped due to 3d widget unstable visual result.
1718
// 3d widget shows grid after fully loaded.
43.9 KB
Loading

src/scripts/app.ts

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1469,7 +1469,21 @@ export class ComfyApp {
14691469
}
14701470
}
14711471

1472-
// Use parameters as fallback when no workflow exists
1472+
if (prompt) {
1473+
try {
1474+
const promptObj =
1475+
typeof prompt === 'string' ? JSON.parse(prompt) : prompt
1476+
if (this.isApiJson(promptObj)) {
1477+
this.loadApiJson(promptObj, fileName)
1478+
return
1479+
}
1480+
} catch (err) {
1481+
console.error('Failed to parse prompt:', err)
1482+
}
1483+
// Fall through to parameters as a last resort
1484+
}
1485+
1486+
// Use parameters strictly as the final fallback
14731487
if (parameters) {
14741488
// Note: Not putting this in `importA1111` as it is mostly not used
14751489
// by external callers, and `importA1111` has no access to `app`.
@@ -1482,18 +1496,25 @@ export class ComfyApp {
14821496
return
14831497
}
14841498

1485-
if (prompt) {
1486-
const promptObj = typeof prompt === 'string' ? JSON.parse(prompt) : prompt
1487-
this.loadApiJson(promptObj, fileName)
1488-
return
1489-
}
1490-
14911499
this.showErrorOnFileLoad(file)
14921500
}
14931501

14941502
// @deprecated
1495-
isApiJson(data: unknown) {
1496-
return _.isObject(data) && Object.values(data).every((v) => v.class_type)
1503+
isApiJson(data: unknown): data is ComfyApiWorkflow {
1504+
if (!_.isObject(data) || Array.isArray(data)) {
1505+
return false
1506+
}
1507+
if (Object.keys(data).length === 0) return false
1508+
1509+
return Object.values(data).every((node) => {
1510+
if (!node || typeof node !== 'object' || Array.isArray(node)) {
1511+
return false
1512+
}
1513+
1514+
const { class_type: classType, inputs } = node as Record<string, unknown>
1515+
const inputsIsRecord = _.isObject(inputs) && !Array.isArray(inputs)
1516+
return typeof classType === 'string' && inputsIsRecord
1517+
})
14971518
}
14981519

14991520
loadApiJson(apiData: ComfyApiWorkflow, fileName: string) {

0 commit comments

Comments
 (0)