langgenius/dify · info · NotFound

last run not found

Error message

last run not found

What it means

HTTP 404 NotFound('last run not found') raised by DraftWorkflowNodeLastRunApi.get (GET /apps/{app_id}/workflows/draft/nodes/{node_id}/last-run) when WorkflowService.get_node_last_run returns None. The draft workflow exists, but no execution record exists for the given node_id (the node was never run in the debugger).

Source

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

    @console_ns.response(404, "Node last run not found")
    @console_ns.response(403, "Permission denied")
    @setup_required
    @login_required
    @account_initialization_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, node_id: str):
        srv = WorkflowService()
        workflow = srv.get_draft_workflow(app_model, session=db.session())
        if not workflow:
            raise NotFound("Workflow not found")
        node_exec = srv.get_node_last_run(
            app_model=app_model,
            workflow=workflow,
            node_id=node_id,
        )
        if node_exec is None:
            raise NotFound("last run not found")
        return WorkflowRunNodeExecutionResponse.model_validate(node_exec, from_attributes=True).model_dump(mode="json")


@console_ns.route("/apps/<uuid:app_id>/workflows/draft/trigger/run")
class DraftWorkflowTriggerRunApi(Resource):
    """
    Full workflow debug - Polling API for trigger events
    Path: /apps/<uuid:app_id>/workflows/draft/trigger/run
    """

    @console_ns.doc("poll_draft_workflow_trigger_run")
    @console_ns.doc(description="Poll for trigger events and execute full workflow when event arrives")
    @console_ns.doc(params={"app_id": "Application ID"})
    @console_ns.expect(
        console_ns.model(
            "DraftWorkflowTriggerRunRequest",
            {
                "node_id": fields.String(required=True, description="Node ID"),

View on GitHub (pinned to ef8544b173)

Solutions

  1. Run the node once (POST .../nodes/{node_id}/run) before fetching its last-run.
  2. Verify the node_id matches a node present in the draft graph.
  3. Treat this 404 as a non-error 'no data yet' state in the UI.
Defensive patterns

Strategy: try-catch

Validate before calling

// Run the node at least once before fetching its last-run.
const lastRun = await safeGetLastRun(appId, nodeId);
if (!lastRun) await runDraftNode(appId, nodeId);

Type guard

const hasLastRun = (r): r is {id: string} => !!r && typeof r.id === 'string';

Try / catch

try {
  return await getNodeLastRun(appId, nodeId);
} catch (e) {
  if (e?.status === 404 && /last run not found/i.test(e?.message)) {
    return null; // no data yet — treat as empty state
  }
  throw e;
}

Prevention

When it happens

Trigger: Polling/reading the last-run result for a node that has never been executed, or whose prior execution record is gone.

Common situations: User opens the node inspector before running the node; node_id is wrong/renamed; execution history was cleared.

Related errors


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