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
- Initialize the draft workflow by saving the workflow graph once (POST /apps/{app_id}/workflows/draft).
- If using the app-creation flow, ensure it bootstraps a draft workflow for ADVANCED_CHAT/WORKFLOW modes.
- Check the workflows table for the app_id; if missing, run the workflow-init step.
- 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
- Run workflow init as part of ADVANCED_CHAT/WORKFLOW app creation.
- Handle 404 by initializing, not by erroring to the user.
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
- draft_workflow_not_sync
- trace_config_not_exist
- patched environment variables require an id
- patched environment variable ids must be unique
- deleted environment variable ids must not be empty
AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12).
Data as JSON: /api/errors/2af4b9e98de3c341.
Report an issue: GitHub.