{"record":{"id":"a0bdabe6d9c772e6","repo":"invoke-ai/InvokeAI","slug":"call-saved-workflow-generator-node-is-malformed","errorCode":null,"errorMessage":"call_saved_workflow generator node is malformed","messagePattern":"call_saved_workflow generator node is malformed","errorType":"exception","errorClass":"UnsupportedWorkflowNodeError","httpStatus":null,"severity":"error","filePath":"invokeai/app/services/session_processor/workflow_call_batch.py","lineNumber":407,"sourceCode":"        \"float_generator_linear_distribution\",\n        \"float_generator_random_distribution_uniform\",\n        \"integer_generator_arithmetic_sequence\",\n        \"integer_generator_linear_distribution\",\n        \"integer_generator_random_distribution_uniform\",\n        \"string_generator_dynamic_prompts_random\",\n    }:\n        return int(value.get(\"count\", 10))\n    return None\n\n\ndef _resolve_generator_items(\n    generator_node: Mapping[str, Any], services: Any, user_id: str | None, maximum_items: int\n) -> list[Any]:\n    generator_node_data = generator_node[\"data\"]\n    node_type = generator_node_data.get(\"type\")\n    inputs = generator_node_data.get(\"inputs\")\n    if not isinstance(node_type, str) or not _is_mapping(inputs):\n        raise UnsupportedWorkflowNodeError(\"call_saved_workflow generator node is malformed\")\n    generator_input = inputs.get(\"generator\")\n    if not _is_mapping(generator_input):\n        raise UnsupportedWorkflowNodeError(\n            f\"call_saved_workflow generator node '{generator_node_data.get('id')}' is missing generator input\"\n        )\n    generator_value = generator_input.get(\"value\")\n    if not _is_mapping(generator_value):\n        raise UnsupportedWorkflowNodeError(\n            f\"call_saved_workflow generator node '{generator_node_data.get('id')}' has invalid generator value\"\n        )\n    declared_item_count = _get_declared_generator_item_count(generator_value)\n    if declared_item_count is not None and declared_item_count > maximum_items:\n        raise TooManySessionsError(\"call_saved_workflow exceeds remaining queue capacity for child workflow executions\")\n    if node_type == \"integer_generator\":\n        return _resolve_integer_generator(generator_value)\n    if node_type == \"float_generator\":\n        return _resolve_float_generator(generator_value)\n    if node_type == \"string_generator\":","sourceCodeStart":389,"sourceCodeEnd":425,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/services/session_processor/workflow_call_batch.py#L389-L425","documentation":"_resolve_generator_items requires each generator node to have data.type as a string and data.inputs as a mapping. If either is missing or wrong-typed, the node is structurally malformed and UnsupportedWorkflowNodeError is raised before any generator is resolved.","triggerScenarios":"build_batch_child_workflow_session_results finds a node whose data lacks 'type' or 'inputs' (or 'inputs' is a list/string/null) while expanding a call_saved_workflow batch.","commonSituations":"Corrupted or truncated workflow JSON, workflows saved by mismatched UI/library versions, hand-editing that dropped the inputs dict.","solutions":["Open the workflow in the InvokeAI editor and re-save so the node's data.type and data.inputs are populated","Inspect the workflow JSON and restore the missing data.type / data.inputs fields on the generator node","Re-create the generator node and reconnect its edges"],"exampleFix":"// before\n{\"id\": \"gen-1\", \"type\": \"invocation\", \"data\": {\"type\": \"integer_generator\"}}\n// after\n{\"id\": \"gen-1\", \"type\": \"invocation\", \"data\": {\"type\": \"integer_generator\", \"inputs\": {\"generator\": {...}}}}","handlingStrategy":"validation","validationCode":"for node in workflow.get(\"nodes\", []):\n    data = node.get(\"data\", {})\n    if not isinstance(data.get(\"type\"), str) or not isinstance(data.get(\"inputs\"), dict):\n        raise ValueError(f\"malformed node {node.get('id')}: need data.type str and data.inputs dict\")","typeGuard":"def is_well_formed_node(node: object) -> TypeGuard[dict]:\n    return (isinstance(node, Mapping) and isinstance(node.get(\"data\"), Mapping)\n            and isinstance(node[\"data\"].get(\"type\"), str) and isinstance(node[\"data\"].get(\"inputs\"), Mapping))","tryCatchPattern":"try:\n    results = build_batch_child_workflow_session_results(...)\nexcept UnsupportedWorkflowNodeError as e:\n    raise WorkflowValidationError(f\"fix node structure before queueing: {e}\") from e","preventionTips":["Validate workflow JSON schema before enqueueing","Avoid manual edits to nodes[].data","Re-save workflows in the UI after version upgrades"],"tags":["workflow","schema-validation","malformed-json"],"backgroundTag":"schema-validation-failed","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}