diff --git a/invokeai/frontend/web/public/locales/en.json b/invokeai/frontend/web/public/locales/en.json index 4028c0e339..76b7dc933a 100644 --- a/invokeai/frontend/web/public/locales/en.json +++ b/invokeai/frontend/web/public/locales/en.json @@ -942,6 +942,7 @@ "sourceNodeFieldDoesNotExist": "Invalid edge: source/output field {{node}}.{{field}} does not exist", "targetNodeFieldDoesNotExist": "Invalid edge: target/input field {{node}}.{{field}} does not exist", "deletedInvalidEdge": "Deleted invalid edge {{source}} -> {{target}}", + "deletedMissingNodeFieldFormElement": "Deleted missing form field: node {{nodeId}} field {{fieldName}}", "noConnectionInProgress": "No connection in progress", "node": "Node", "nodeOutputs": "Node Outputs", diff --git a/invokeai/frontend/web/src/features/nodes/util/workflow/validateWorkflow.ts b/invokeai/frontend/web/src/features/nodes/util/workflow/validateWorkflow.ts index f80f8b6eae..fe79bb3efc 100644 --- a/invokeai/frontend/web/src/features/nodes/util/workflow/validateWorkflow.ts +++ b/invokeai/frontend/web/src/features/nodes/util/workflow/validateWorkflow.ts @@ -6,7 +6,7 @@ import { isModelIdentifierFieldInputInstance, } from 'features/nodes/types/field'; import type { WorkflowV3 } from 'features/nodes/types/workflow'; -import { buildNodeFieldElement, isWorkflowInvocationNode } from 'features/nodes/types/workflow'; +import { buildNodeFieldElement, isNodeFieldElement, isWorkflowInvocationNode } from 'features/nodes/types/workflow'; import { getNeedsUpdate, updateNode } from 'features/nodes/util/node/nodeUpdate'; import { t } from 'i18next'; import type { JsonObject } from 'type-fest'; @@ -252,5 +252,22 @@ export const validateWorkflow = async ( } } + for (const element of Object.values(_workflow.form.elements)) { + if (!isNodeFieldElement(element)) { + continue; + } + const { nodeId, fieldName } = element.data.fieldIdentifier; + const node = nodes.filter(isWorkflowInvocationNode).find(({ id }) => id === nodeId); + const field = node?.data.inputs[fieldName]; + if (!field) { + // The form element field no longer exists on the node + delete _workflow.form.elements[element.id]; + warnings.push({ + message: t('nodes.deletedMissingNodeFieldFormElement', { nodeId, fieldName }), + data: { nodeId, fieldName }, + }); + } + } + return { workflow: _workflow, warnings }; };