langgenius/dify · error · WorkflowInUseError
{str(e)}
Error message
{str(e)} What it means
HTTP 400 from `PipelineWorkflowItemApi.delete`'s `WorkflowInUseError` branch. After passing the active-binding guard, the handler calls `WorkflowService.delete_workflow`; if the workflow is still referenced by an app (per `WorkflowInUseError`, a `ValueError` subclass defined in `services/errors/workflow_service.py`), the message is re-emitted as `abort(400, description=str(e))`.
Source
Thrown at api/controllers/console/datasets/rag_pipeline/rag_pipeline_workflow.py:788
@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()
workflow_ref = WorkflowRefService.create_pipeline_workflow_ref(pipeline, workflow_id)
with sessionmaker(db.engine).begin() as session:
try:
workflow_service.delete_workflow(
session=session,
workflow_ref=workflow_ref,
)
except WorkflowInUseError as e:
abort(400, description=str(e))
except DraftWorkflowDeletionError as e:
abort(400, description=str(e))
except ValueError as e:
raise NotFound(str(e))
return None, 204
@console_ns.route("/rag/pipelines/<uuid:pipeline_id>/workflows/published/processing/parameters")
class PublishedRagPipelineSecondStepApi(Resource):
@console_ns.doc(params=query_params_from_model(NodeIdQuery))
@console_ns.response(200, "Success", console_ns.models[RagPipelineStepParametersResponse.__name__])
@setup_required
@login_required
@account_initialization_required
@get_rag_pipeline
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)View on GitHub (pinned to ef8544b173)
Solutions
- Find and rebind or remove apps referencing the workflow before retrying the delete.
- Inspect `WorkflowInUseError`'s message (forwarded verbatim) to identify the referencing app.
- Sequence migrations so app rebinding completes before workflow cleanup.
- Retry idempotently after the referencing app is no longer bound.
Example fix
# before delete workflow -> 400 WorkflowInUseError: referenced by app <id> # after # 1. update the app's workflow_ref to a different version # 2. delete the now-unreferenced workflow
Defensive patterns
Strategy: try-catch
Validate before calling
from services.workflow_service import WorkflowService # Before deleting, check whether any app references the workflow: # WorkflowInUseError is raised inside WorkflowService.delete_workflow, # so pre-check by listing apps bound to the workflow_ref.
Try / catch
try:
client.delete(f"/rag/pipelines/{pid}/workflows/{wid}")
except HTTPError as err:
if err.response.status_code == 400:
# message forwarded from WorkflowInUseError — rebind/remove referencing app, then retry
...
raise Prevention
- Rebind or remove apps referencing a workflow before deleting it.
- Read the forwarded message to find the referencing app id.
- Sequence migrations so app rebinding completes before workflow cleanup.
- Retry deletes idempotently after the dependency is cleared.
When it happens
Trigger: DELETE on a published workflow version that is still referenced by some app (the service raises `WorkflowInUseError`). Distinct from the active-pipeline guard (946) — this fires when *any* app still depends on the workflow.
Common situations: Deleting a workflow version that an app still points at; deleting too early during a migration before apps were rebound; concurrent publish/delete race where another flow bound an app to the workflow.
Related errors
- source workflow must be published
- Cannot delete workflow that is currently in use by pipeline
- usage_missing_arg
- usage_invalid_flag
- usage_missing_arg
AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12).
Data as JSON: /api/errors/dcf4b424b8e77782.
Report an issue: GitHub.