conductor-oss/conductor · error · NotFoundException

No such workflow found by id: %s

Error message

No such workflow found by id: %s

What it means

Thrown by getWorkflowModelFromExecutionDAO when executionDAO.getWorkflow(workflowId, includeTasks) returns null. This method deliberately reads ONLY the primary ExecutionDAO (the source of truth) and never falls back to the IndexDAO, so it is used for control-flow decisions that must not rely on eventually-consistent index data. A null result means the workflow is genuinely absent from the primary store.

Source

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

        populateWorkflowAndTaskPayloadData(workflowModel);
        return workflowModel;
    }

    /**
     * Fetches the {@link WorkflowModel} from the primary execution store only.
     *
     * <p>Unlike {@link #getWorkflowModel(String, boolean)}, this method does not fall back to
     * {@link IndexDAO}. Use it for control-flow decisions that must rely on the source of truth.
     *
     * @param workflowId the id of the workflow to be fetched
     * @param includeTasks if true, fetches the {@link Task} data in the workflow.
     * @return the {@link WorkflowModel} object from {@link ExecutionDAO}
     * @throws NotFoundException no such {@link WorkflowModel} is found in {@link ExecutionDAO}.
     */
    public WorkflowModel getWorkflowModelFromExecutionDAO(String workflowId, boolean includeTasks) {
        WorkflowModel workflow = executionDAO.getWorkflow(workflowId, includeTasks);
        if (workflow == null) {
            throw new NotFoundException("No such workflow found by id: %s", workflowId);
        }
        populateWorkflowAndTaskPayloadData(workflow);
        return workflow;
    }

    /**
     * Fetches the {@link Workflow} object from the data store given the id. Attempts to fetch from
     * {@link ExecutionDAO} first, if not found, attempts to fetch from {@link IndexDAO}.
     *
     * @param workflowId the id of the workflow to be fetched
     * @param includeTasks if true, fetches the {@link Task} data in the workflow.
     * @return the {@link Workflow} object
     * @throws NotFoundException no such {@link Workflow} is found.
     * @throws TransientException parsing the {@link Workflow} object fails.
     */
    public Workflow getWorkflow(String workflowId, boolean includeTasks) {
        return getWorkflowModelFromDataStore(workflowId, includeTasks).toWorkflow();
    }

View on GitHub (pinned to cf7c3e4a8a)

Solutions

  1. Confirm the workflowId is correct and was created (check metadata/ExecutionDAO directly, not just the index).
  2. If the workflow should exist, verify it was not removed by the sweeper, an explicit removeWorkflow call, or a TTL expiry.
  3. If reading for display/search (not control flow), use getWorkflow/getWorkflowModel instead, which falls back to the IndexDAO.
  4. Guard the caller: treat NotFoundException as a terminal 'workflow not present' signal rather than retrying blindly.

Example fix

// before - control-flow read that needs source of truth
WorkflowModel wf = executionDAOFacade.getWorkflowModelFromExecutionDAO(id, true);
// after - tolerate missing workflow in control flow
WorkflowModel wf;
try {
    wf = executionDAOFacade.getWorkflowModelFromExecutionDAO(id, true);
} catch (NotFoundException e) {
    LOGGER.warn("Workflow {} no longer in primary store, skipping", id);
    return;
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
    WorkflowModel wf = executionDAOFacade.getWorkflowModelFromExecutionDAO(workflowId, includeTasks);
} catch (NotFoundException e) {
    // workflow absent from source of truth; treat as terminal for this control-flow branch
    LOGGER.warn("Workflow {} not in primary store", workflowId);
}

Prevention

When it happens

Trigger: Calling getWorkflowModelFromExecutionDAO with a workflowId that was never created, was already removed/purged from the ExecutionDAO, or whose ID is malformed. Also fires during a race where the workflow has been deleted but a pending decider/sweeper call still references it.

Common situations: A client sends a stale or fabricated workflow id. A retry/queue message references a workflow that has already been archived and removed. A split-brain or replica-lag in a distributed ExecutionDAO (e.g. Cassandra/DynamoDB) momentarily returns null before the write is visible.

Related errors


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