conductor-oss/conductor · error · TransientException

Error reading workflow: %s

Error message

Error reading workflow: %s

What it means

Thrown as a TransientException wrapping an IOException when objectMapper.readValue fails to deserialize the RAW_JSON_FIELD retrieved from the IndexDAO. The workflow JSON was found in the index but cannot be parsed back into a WorkflowModel — i.e. the index holds corrupt or schema-incompatible data. Marked transient because it is treated as a recoverable (often retryable) data-access failure rather than a definitive 'does not exist'.

Source

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

        WorkflowModel workflow = executionDAO.getWorkflow(workflowId, includeTasks);
        if (workflow == null) {
            LOGGER.debug("Workflow {} not found in executionDAO, checking indexDAO", workflowId);
            String json = indexDAO.get(workflowId, RAW_JSON_FIELD);
            if (json == null) {
                String errorMsg = String.format("No such workflow found by id: %s", workflowId);
                LOGGER.error(errorMsg);
                throw new NotFoundException(errorMsg);
            }

            try {
                workflow = objectMapper.readValue(json, WorkflowModel.class);
                if (!includeTasks) {
                    workflow.getTasks().clear();
                }
            } catch (IOException e) {
                String errorMsg = String.format("Error reading workflow: %s", workflowId);
                LOGGER.error(errorMsg);
                throw new TransientException(errorMsg, e);
            }
        }
        return workflow;
    }

    /**
     * Retrieve all workflow executions with the given correlationId and workflow type Uses the
     * {@link IndexDAO} to search across workflows if the {@link ExecutionDAO} cannot perform
     * searches across workflows.
     *
     * @param workflowName, workflow type to be queried
     * @param correlationId the correlation id to be queried
     * @param includeTasks if true, fetches the {@link Task} data within the workflows
     * @return the list of {@link Workflow} executions matching the correlationId
     */
    public List<Workflow> getWorkflowsByCorrelationId(
            String workflowName, String correlationId, boolean includeTasks) {
        if (!executionDAO.canSearchAcrossWorkflows()) {

View on GitHub (pinned to cf7c3e4a8a)

Solutions

  1. Inspect the raw JSON in the index for that workflowId to see what fails to parse.
  2. If a schema change broke backward compatibility, add Jackson @JsonIgnoreProperties(ignoreUnknown=true) or migrate the archived documents.
  3. If the document is genuinely corrupt, remove it from the index so the read fails fast with NotFoundException instead of a parse loop.
  4. Because it is a TransientException, ensure callers retry with backoff but cap retries to avoid hammering a permanently corrupt record.
Defensive patterns

Strategy: retry

Try / catch

try {
    Workflow wf = executionDAOFacade.getWorkflow(workflowId, true);
} catch (TransientException e) {
    // index JSON present but unparseable -> retry with backoff, then surface if persistent
}

Prevention

When it happens

Trigger: The indexDAO returned a non-null JSON string that is malformed, truncated, or serialized by an incompatible Conductor version whose WorkflowModel schema differs. Fires inside getWorkflowModelFromDataStore's catch (IOException) after the fallback index read.

Common situations: A version upgrade changed WorkflowModel fields and old archived JSON no longer deserializes. The index (Elasticsearch) returned a partial/corrupted document. Custom Jackson modules or polymorphic task types whose registered types changed.

Related errors


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