langgenius/dify · error · NotFound
Workflow not found
Error message
Workflow not found
What it means
Raised as NotFound("Workflow not found") (HTTP 404) in RagPipelineByIdApi.patch (PATCH /rag/pipelines/<pipeline_id>/workflows/<workflow_id>) when update_workflow returns a falsy value. After building a WorkflowRef from the path ids and applying update_data, the service cannot find a matching workflow row to update, so the controller returns 404.
Source
Thrown at api/controllers/console/datasets/rag_pipeline/rag_pipeline_workflow.py:760
update_data = req_data.model_dump(exclude_unset=True)
if not update_data:
return {"message": "No valid fields to update"}, 400
rag_pipeline_service = RagPipelineService(db.session())
workflow_ref = WorkflowRefService.create_pipeline_workflow_ref(pipeline, workflow_id)
# Create a session and manage the transaction
with sessionmaker(db.engine, expire_on_commit=False).begin() as session:
workflow = rag_pipeline_service.update_workflow(
session=session,
account_id=current_user.id,
data=update_data,
workflow_ref=workflow_ref,
)
if not workflow:
raise NotFound("Workflow not found")
return dump_response(WorkflowResponse, workflow)
@console_ns.response(204, "Workflow deleted successfully")
@setup_required
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@get_rag_pipeline
def delete(self, pipeline: Pipeline, workflow_id: str):
"""
Delete a published workflow version that is not currently active on the pipeline.
"""
if pipeline.workflow_id == workflow_id:
abort(400, description=f"Cannot delete workflow that is currently in use by pipeline '{pipeline.id}'")
workflow_service = WorkflowService()View on GitHub (pinned to ef8544b173)
Solutions
- Re-fetch the workflow list to obtain a valid, current workflow_id before PATCHing.
- Verify pipeline_id and workflow_id belong together.
- On the client, treat 404 as 'workflow no longer exists' and refresh the editor.
- Ensure at least one updatable field is set so you do not hit the earlier 400 first.
Example fix
// before
PATCH /rag/pipelines/<id>/workflows/<wrong-id> {"name": "x"} // -> 404
// after
wf = await GET /rag/pipelines/<id>/workflows
PATCH /rag/pipelines/<id>/workflows/<wf[0].id> {"name": "x"} Defensive patterns
Strategy: try-catch
Validate before calling
async function patchWorkflow(pipelineId, workflowId, data) {
if (!data || Object.keys(data).length === 0) throw new Error('no fields to update');
return fetch(`/rag/pipelines/${pipelineId}/workflows/${workflowId}`, {
method: 'PATCH', headers: {'Content-Type':'application/json'}, body: JSON.stringify(data)
});
} Type guard
function hasUpdatableFields(data) { return !!data && typeof data === 'object' && Object.keys(data).length > 0; } Try / catch
try { await patchWorkflow(id, wfId, data); } catch (e) { if (e.status === 404) refreshWorkflows(); else if (e.status === 400) notifyNoFields(); else throw e; } Prevention
- Send at least one updatable field.
- Refresh the workflow list after a 404.
- Confirm pipeline_id and workflow_id are from the same context.
When it happens
Trigger: PATCHing a workflow_id that does not exist for the given pipeline, or one whose WorkflowRef cannot be resolved. The `if not workflow` branch then raises NotFound. (An empty update_data body is handled earlier as a 400, not here.)
Common situations: Editing a workflow that was just deleted by another user; workflow_id from a different pipeline; UI holding an old id after the list refreshed; sending an update after the workflow was archived/removed.
Related errors
AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12).
Data as JSON: /api/errors/0e04fab20a6520f4.
Report an issue: GitHub.