{"record":{"id":"afc29137feacfd3d","repo":"conductor-oss/conductor","slug":"input-s-is-invalid-cannot-deserialize-a-list-o","errorCode":null,"errorMessage":"Input '%s' is invalid. Cannot deserialize a list of Workflow Tasks from '%s'","messagePattern":"Input '(.+?)' is invalid\\. Cannot deserialize a list of Workflow Tasks from '(.+?)'","errorType":"exception","errorClass":"TerminateWorkflowException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/com/netflix/conductor/core/execution/mapper/ForkJoinDynamicTaskMapper.java","lineNumber":409,"sourceCode":"                dynamicForkWorkflowTasks, (Map<String, Map<String, Object>>) dynamicForkTasksInput);\n    }\n\n    private List<WorkflowTask> getDynamicForkWorkflowTasks(\n            String dynamicForkTaskParam, Map<String, Object> input) {\n        Object dynamicForkTasksJson = input.get(dynamicForkTaskParam);\n        try {\n            List<WorkflowTask> tasks =\n                    objectMapper.convertValue(dynamicForkTasksJson, ListOfWorkflowTasks);\n            for (var task : tasks) {\n                if (task.getTaskReferenceName() == null) {\n                    throw new RuntimeException(\n                            \"One of the tasks had a null/missing taskReferenceName\");\n                }\n            }\n            return tasks;\n        } catch (Exception e) {\n            LOGGER.warn(\"IllegalArgumentException in getDynamicForkTasksAndInput\", e);\n            throw new TerminateWorkflowException(\n                    String.format(\n                            \"Input '%s' is invalid. Cannot deserialize a list of Workflow Tasks from '%s'\",\n                            dynamicForkTaskParam, dynamicForkTasksJson));\n        }\n    }\n\n    Pair<List<WorkflowTask>, Map<String, Map<String, Object>>> getDynamicTasksSimple(\n            WorkflowTask workflowTask,\n            Map<String, Object> input,\n            String parentTaskName,\n            boolean hasMoreThanOneFork)\n            throws TerminateWorkflowException {\n\n        String forkSubWorkflowName = (String) input.get(\"forkTaskWorkflow\");\n        String forkSubWorkflowVersionStr = (String) input.get(\"forkTaskWorkflowVersion\");\n        Integer forkSubWorkflowVersion = null;\n        try {\n            forkSubWorkflowVersion = Integer.parseInt(forkSubWorkflowVersionStr);","sourceCodeStart":391,"sourceCodeEnd":427,"githubUrl":"https://github.com/conductor-oss/conductor/blob/cf7c3e4a8adfb158be778ab1ec525323c363cd3a/core/src/main/java/com/netflix/conductor/core/execution/mapper/ForkJoinDynamicTaskMapper.java#L391-L427","documentation":"Thrown by getDynamicForkWorkflowTasks() when ObjectMapper.convertValue() fails to deserialize the input JSON into a List<WorkflowTask>. This happens when the input at the dynamicForkTaskParam key is not valid WorkflowTask JSON — wrong structure, missing fields, or a completely wrong type. The catch also covers the case where a deserialized task has a null taskReferenceName (the inner RuntimeException is caught by the same catch block).","triggerScenarios":"The dynamic fork tasks JSON contains objects that cannot be mapped to WorkflowTask (missing required fields like name or type). The JSON is a single object instead of an array. One of the forked tasks has a null or missing taskReferenceName field.","commonSituations":"Workflow designer provides inline JSON for forked tasks with a typo in a field name (e.g., 'taskReference' instead of 'taskReferenceName'). The dynamic fork task list is empty or contains a string instead of a task object. A field that should be a string is provided as a number.","solutions":["Inspect the dynamicForkTasksJson value in the error message — it shows exactly what failed to deserialize.","Ensure each element in the forked tasks array has at minimum: name, taskReferenceName, and type.","Validate the JSON structure against the WorkflowTask schema before providing it as fork task input.","If a task has a null taskReferenceName, add an explicit non-empty reference name to every forked task."],"exampleFix":"// before — missing taskReferenceName\n\"forkedTasks\": [\n  { \"name\": \"http_task\", \"type\": \"SIMPLE\" }\n]\n\n// after\n\"forkedTasks\": [\n  { \"name\": \"http_task\", \"taskReferenceName\": \"http_0\", \"type\": \"SIMPLE\" }\n]","handlingStrategy":"validation","validationCode":"// Validate forked tasks JSON can be deserialized before execution\nObject forkTasksJson = input.get(dynamicForkTaskParam);\ntry {\n    List<WorkflowTask> tasks = objectMapper.convertValue(forkTasksJson,\n        new TypeReference<List<WorkflowTask>>() {});\n    for (WorkflowTask t : tasks) {\n        if (t.getTaskReferenceName() == null) {\n            throw new IllegalArgumentException(\"Missing taskReferenceName\");\n        }\n    }\n} catch (Exception e) {\n    throw new IllegalArgumentException(\"Invalid fork tasks JSON: \" + e.getMessage());\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate the dynamic fork tasks JSON against the WorkflowTask schema.","Ensure every forked task has a non-null taskReferenceName.","Use JSON schema validation on workflow input before execution."],"tags":["fork-join-dynamic","deserialize","terminate","workflow-task","json"],"backgroundTag":null,"analyzedSha":"cf7c3e4a8adfb158be778ab1ec525323c363cd3a","analyzedAt":"2026-08-14T03:33:19.897Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}