langgenius/dify · error · NotFoundError
not_found
not_found
Error message
Workflow run not found
What it means
Thrown by GET /apps/{app_id}/workflow-runs/{run_id} when WorkflowRunService.get_workflow_run cannot locate a run with the given run_id for the app. The run may not exist or may belong to a different app. Returned as 404 code 'not_found'.
Source
Thrown at api/controllers/console/app/workflow_run.py:394
"Workflow run detail retrieved successfully",
console_ns.models[WorkflowRunDetailResponse.__name__],
)
@console_ns.response(404, "Workflow run not found")
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_CREATE_AND_MANAGEMENT)
@get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
def get(self, app_model: App, run_id: UUID):
"""
Get workflow run detail
"""
run_id_str = str(run_id)
workflow_run_service = WorkflowRunService()
workflow_run = workflow_run_service.get_workflow_run(app_model=app_model, run_id=run_id_str)
if workflow_run is None:
raise NotFoundError("Workflow run not found")
return WorkflowRunDetailResponse.model_validate(workflow_run, from_attributes=True).model_dump(mode="json")
@console_ns.route("/apps/<uuid:app_id>/workflow-runs/<uuid:run_id>/node-executions")
class WorkflowRunNodeExecutionListApi(Resource):
@console_ns.doc("get_workflow_run_node_executions")
@console_ns.doc(description="Get workflow run node execution list")
@console_ns.doc(params={"app_id": "Application ID", "run_id": "Workflow run ID"})
@console_ns.response(
200,
"Node executions retrieved successfully",
console_ns.models[WorkflowRunNodeExecutionListResponse.__name__],
)
@console_ns.response(404, "Workflow run not found")
@setup_required
@login_required
@account_initialization_requiredView on GitHub (pinned to ef8544b173)
Solutions
- List runs via GET /apps/{app_id}/workflow-runs to obtain a valid run_id before fetching detail.
- Confirm run_id belongs to app_id; cross-app references return None.
- If the run was just published, retry after the run record is committed (brief propagation window).
- Check the workflow_runs table for the run_id to rule out deletion.
Defensive patterns
Strategy: try-catch
Validate before calling
const runs = await get(`/apps/${appId}/workflow-runs`);
const exists = runs.data.some(r => r.id === runId);
if (!exists) { /* do not fetch detail */ } Try / catch
try {
await get(`/apps/${appId}/workflow-runs/${runId}`);
} catch (e) {
if (e.code === 'not_found' && /workflow run not found/i.test(e.message)) {
// show 'run expired or unknown' state, refresh runs list
} else { throw e; }
} Prevention
- Use run ids obtained from the workflow-runs list, not from log lines.
- Treat deep links to runs as best-effort: the run may be purged by retention.
When it happens
Trigger: GET /console/api/apps/{app_id}/workflow-runs/{run_id} where run_id is unknown, was deleted, belongs to another app, or is malformed (but passed URL UUID parsing).
Common situations: User clicks a stale run link from history/email after the run was purged; copying a run_id across environments; race condition where the run is still being committed; passing the app run id instead of the workflow run id.
Related errors
- Conversation Not Exists.
- Webhook trigger not found for this node
- Trigger not found
- app_not_found
- Draft workflow not found, pipeline_id={pipeline.id}
AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12).
Data as JSON: /api/errors/cfa1b82c73fbca80.
Report an issue: GitHub.