conductor-oss/conductor · error · TransientException

Workflow can not be serialized to json

Error message

Workflow can not be serialized to json

What it means

Thrown as a TransientException when objectMapper.writeValueAsString(workflow) raises a JsonProcessingException during removeWorkflowIndex while archiving a terminal workflow. The code writes the full workflow as RAW_JSON_FIELD plus an ARCHIVED_FIELD=true into the index before removing it from the DAO; if serialization fails the whole removal is aborted to avoid data loss (the DAO record is kept so it can be retried).

Solutions

  1. Inspect the workflow's tasks and payloads for non-serializable or circular-reference values.
  2. Ensure the ObjectMapper bean has all required Jackson modules registered (e.g. jdk8, JavaTime).
  3. If you must remove the workflow despite serialization failure, call remove with archiveWorkflow=false so the index entry is deleted instead of archived.
  4. Retry after fixing the payload; the DAO record is preserved, so nothing is lost.
Defensive patterns

Strategy: try-catch

Try / catch

try {
    executionDAOFacade.removeWorkflow(workflowId, /* archive */ true);
} catch (TransientException e) {
    // serialization failed during archival; DAO record preserved -> safe to retry after fix
}

Prevention

When it happens

Trigger: Archiving (archiveWorkflow=true) a workflow whose model graph contains a value Jackson cannot serialize — e.g. a non-serializable task input/output, a self-referencing object, or a type without a matching Jackson serializer.

Common situations: A workflow task payload holds a custom Java type or an unserializable runtime object. A Jackson ObjectMapper configuration mismatch (missing modules) between the producing and archiving paths. Circular references in dynamic payload data.

Related errors


AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14). Data as JSON: /api/errors/92a5c1ec72c60a90. Report an issue: GitHub.

Appendix: source

Thrown at core/src/main/java/com/netflix/conductor/core/dal/ExecutionDAOFacade.java:371

     *
     * @param workflowId the id of the workflow to be removed
     * @param archiveWorkflow if true, the workflow and associated tasks will be archived in the
     *     {@link IndexDAO} before removal from {@link ExecutionDAO}.
     */
    public void removeWorkflow(String workflowId, boolean archiveWorkflow) {
        WorkflowModel workflow = getWorkflowModelFromDataStore(workflowId, true);

        // Index operations happen before DAO removal to prevent data loss on index failures.
        try {
            removeWorkflowIndex(workflow, archiveWorkflow);
        } catch (NotFoundException e) {
            if (archiveWorkflow) {
                throw e;
            }
            // Idempotent deletion: missing index records should not block DAO removal.
            LOGGER.info("Workflow {} not found in index during removal, continuing", workflowId, e);
        } catch (JsonProcessingException e) {
            throw new TransientException("Workflow can not be serialized to json", e);
        }

        // Task index removals run before DAO deletion for the same consistency guarantees.
        workflow.getTasks()
                .forEach(
                        task -> {
                            try {
                                removeTaskIndex(workflow, task, archiveWorkflow);
                            } catch (NotFoundException e) {
                                if (archiveWorkflow) {
                                    throw e;
                                }
                                // Idempotent deletion: missing index records should not block DAO
                                // removal.
                                LOGGER.info(
                                        "Task {} of workflow {} not found in index during removal, continuing",
                                        task.getTaskId(),
                                        workflowId,

View on GitHub (pinned to cf7c3e4a8a)