langgenius/dify · warning · DraftWorkflowNotExist

draft_workflow_not_exist

draft_workflow_not_exist

Error message

Draft workflow need to be initialized.

What it means

Raised as DraftWorkflowNotExist in DraftWorkflowApi.get when WorkflowService.get_draft_workflow returns None (api/controllers/console/app/workflow.py:589-590). The app has no draft workflow row — the workflow has not been initialized. Only applies to ADVANCED_CHAT and WORKFLOW mode apps (enforced by the @get_app_model decorator).

Source

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

        console_ns.models[WorkflowResponse.__name__],
    )
    @console_ns.response(404, "Draft workflow not found")
    @setup_required
    @login_required
    @account_initialization_required
    @edit_permission_required
    @rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
    @get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
    def get(self, app_model: App):
        """
        Get draft workflow
        """
        # fetch draft workflow by app_model
        workflow_service = WorkflowService()
        workflow = workflow_service.get_draft_workflow(app_model=app_model, session=db.session())

        if not workflow:
            raise DraftWorkflowNotExist()

        from services.agent.workflow_publish_service import WorkflowAgentPublishService

        # Return workflow with response-only Agent node job projection so the
        # front-end can treat draft graph node data as the editing source.
        response = WorkflowResponse.model_validate(workflow, from_attributes=True).model_dump(mode="json")
        response["graph"] = WorkflowAgentPublishService.project_draft_bindings_to_graph(
            session=db.session(),
            draft_workflow=workflow,
        )
        return response

    @setup_required
    @login_required
    @account_initialization_required
    @get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
    @console_ns.doc("sync_draft_workflow")
    @console_ns.doc(description="Sync draft workflow configuration")

View on GitHub (pinned to ef8544b173)

Solutions

  1. Initialize the draft workflow by saving the workflow graph once (POST /apps/{app_id}/workflows/draft).
  2. If using the app-creation flow, ensure it bootstraps a draft workflow for ADVANCED_CHAT/WORKFLOW modes.
  3. Check the workflows table for the app_id; if missing, run the workflow-init step.
  4. Refresh the app after initialization.
Defensive patterns

Strategy: try-catch

Validate before calling

// Initialize a draft workflow if GET returns 404
async function loadOrInitDraft(appId) {
  try { return await getDraftWorkflow(appId) }
  catch (e) { if (e.code === 'draft_workflow_not_exist') return await initDraftWorkflow(appId); throw e }
}

Try / catch

try {
  await getDraftWorkflow(appId)
} catch (e) {
  if (e.code === 'draft_workflow_not_exist') { await initDraftWorkflow(appId); return getDraftWorkflow(appId) }
  throw e
}

Prevention

When it happens

Trigger: GET /apps/{app_id}/workflows/draft for an ADVANCED_CHAT/WORKFLOW app that has never had its draft workflow created, or whose draft was deleted. The front-end typically calls this on app open.

Common situations: Newly created advanced-chat/workflow app before first save; draft workflow row removed by cleanup/migration; app imported without its workflow; race where the app exists but workflow init has not run.

Related errors


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