langgenius/dify · error · NotFound

Workflow not found

Error message

Workflow not found

What it means

HTTP 404 NotFound('Workflow not found') raised by WorkflowByIdApi.patch (PATCH /apps/{app_id}/workflows/{workflow_id}) when WorkflowService.update_workflow returns a falsy workflow after the update transaction. The route resolves the path workflow_id via WorkflowRefService.create_app_workflow_ref; if no workflow matches that ref for the app, update returns None and the 404 fires.

Source

Thrown at api/controllers/console/app/workflow.py:1610

            update_data["marked_comment"] = args.marked_comment

        if not update_data:
            return {"message": "No valid fields to update"}, 400

        workflow_service = WorkflowService()
        workflow_ref = WorkflowRefService.create_app_workflow_ref(app_model, workflow_id)

        # Create a session and manage the transaction
        with sessionmaker(db.engine, expire_on_commit=False).begin() as session:
            workflow = workflow_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")

            response = dump_response(WorkflowResponse, _WorkflowResponseSource(workflow, session=session))

        return response

    @setup_required
    @login_required
    @account_initialization_required
    @get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
    @edit_permission_required
    @rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_EDIT)
    @console_ns.response(204, "Workflow deleted successfully")
    def delete(self, app_model: App, workflow_id: str):
        """
        Delete workflow
        """
        workflow_service = WorkflowService()
        workflow_ref = WorkflowRefService.create_app_workflow_ref(app_model, workflow_id)

View on GitHub (pinned to ef8544b173)

Solutions

  1. Refresh the workflow list (GET /apps/{app_id}/workflows) and PATCH the correct existing id.
  2. Confirm the workflow_id belongs to the same app_id.
  3. If the workflow was deleted, recreate or restore it before patching.
Defensive patterns

Strategy: validation

Validate before calling

// Confirm the workflow id exists for this app before PATCH.
const exists = await listWorkflows(appId).then(list => list.some(w => w.id === workflowId));
if (!exists) { refreshWorkflowList(); return; }

Type guard

const isWorkflowOfApp = (w, appId): boolean => !!w && w.app_id === appId;

Try / catch

try {
  return await patchWorkflow(appId, workflowId, patch);
} catch (e) {
  if (e?.status === 404 && /Workflow not found/i.test(e?.message)) {
    await refreshWorkflowList(); return;
  }
  throw e;
}

Prevention

When it happens

Trigger: Patching marked_name/marked_comment on a workflow_id that does not exist for the app, was deleted, or whose ref does not resolve.

Common situations: Stale id kept by the client after the workflow was deleted/published; cross-app id; ref-lookup mismatch after a migration.

Related errors


AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12). Data as JSON: /api/errors/00465860ed85c4ad. Report an issue: GitHub.