langgenius/dify · warning · NotFound
last run not found
Error message
last run not found
What it means
Raised as NotFound("last run not found") (HTTP 404) in RagPipelineWorkflowLastRunApi.get after the draft workflow is found but get_node_last_run returns None. It means the node exists in the draft context but has never produced an execution record, so there is no 'last run' to return.
Source
Thrown at api/controllers/console/datasets/rag_pipeline/rag_pipeline_workflow.py:1012
"Node last run retrieved successfully",
console_ns.models[WorkflowRunNodeExecutionResponse.__name__],
)
@setup_required
@login_required
@account_initialization_required
@get_rag_pipeline
def get(self, pipeline: Pipeline, node_id: str):
rag_pipeline_service = RagPipelineService(db.session())
workflow = rag_pipeline_service.get_draft_workflow(pipeline=pipeline)
if not workflow:
raise NotFound("Workflow not found")
node_exec = rag_pipeline_service.get_node_last_run(
pipeline=pipeline,
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("/rag/pipelines/transform/datasets/<uuid:dataset_id>")
class RagPipelineTransformApi(Resource):
@console_ns.response(200, "Success", console_ns.models[RagPipelineOpaqueResponse.__name__])
@setup_required
@login_required
@account_initialization_required
@with_current_user
@with_session
def post(self, session: Session, current_user: Account, dataset_id: UUID):
if not (current_user.has_edit_permission or current_user.is_dataset_operator):
raise Forbidden()
dataset_id_str = str(dataset_id)
rag_pipeline_transform_service = RagPipelineTransformService()
result = rag_pipeline_transform_service.transform_dataset(dataset_id_str, session)View on GitHub (pinned to ef8544b173)
Solutions
- Run the node first (POST .../draft/nodes/<node_id>/run) before asking for its last run.
- Treat this 404 as 'node has no execution history' in the UI rather than an error.
- Confirm node_id belongs to an executable node type.
- If history is expected, check retention/cleanup settings that may have removed old executions.
Example fix
// before GET .../draft/nodes/<node>/last-run // -> 404 last run not found // after await POST .../draft/nodes/<node>/run GET .../draft/nodes/<node>/last-run
Defensive patterns
Strategy: try-catch
Validate before calling
async function getLastRunOrCreate(pipelineId, nodeId, inputs) {
const r = await fetch(`/rag/pipelines/${pipelineId}/workflows/draft/nodes/${nodeId}/last-run`);
if (r.status === 404) {
await fetch(`/rag/pipelines/${pipelineId}/workflows/draft/nodes/${nodeId}/run`, { method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify({ inputs }) });
return fetch(`/rag/pipelines/${pipelineId}/workflows/draft/nodes/${nodeId}/last-run`);
}
return r;
} Type guard
function hasExecutionHistory(exec) { return !!exec && !!exec.id; } Try / catch
try { return await getLastRunOrCreate(id, nodeId, inputs); } catch (e) { /* 'last run not found' handled by run-first fallback */ throw e; } Prevention
- Run the node at least once before asking for last-run.
- Treat 'last run not found' as 'no history', not a hard error.
- Confirm the node type produces execution rows.
When it happens
Trigger: Calling GET .../workflows/draft/nodes/<node_id>/last-run for a node that has never been executed (newly added node, draft saved but never run), or whose execution records were purged. The draft workflow resolves fine, but node_exec is None.
Common situations: Requesting last-run right after adding a node to the graph; node is an input/trigger type that does not create execution rows; executions cleaned up by retention.
Related errors
AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12).
Data as JSON: /api/errors/0dd93078ba58761d.
Report an issue: GitHub.