langgenius/dify · error · ValueError

Workflow node execution not found

Error message

Workflow node execution not found

What it means

Raised as a raw ValueError when RagPipelineService.run_draft_workflow_node returns None while running a single draft-workflow node (POST /rag/pipelines/<pipeline_id>/workflows/draft/nodes/<node_id>/run). Because it is a plain ValueError rather than a werkzeug HTTPException, Flask surfaces it as an HTTP 500 instead of a meaningful 4xx. The service returns None when no WorkflowNodeExecution record can be produced for the given node.

Source

Thrown at api/controllers/console/datasets/rag_pipeline/rag_pipeline_workflow.py:500

    @edit_permission_required
    @rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
    @account_initialization_required
    @with_current_user
    @get_rag_pipeline
    @model_validate(NodeRunRequiredPayload)
    def post(self, req_data: NodeRunRequiredPayload, current_user: Account, pipeline: Pipeline, node_id: str):
        """
        Run draft workflow node
        """
        inputs = req_data.inputs

        rag_pipeline_service = RagPipelineService(db.session())
        workflow_node_execution = rag_pipeline_service.run_draft_workflow_node(
            pipeline=pipeline, node_id=node_id, user_inputs=inputs, account=current_user
        )

        if workflow_node_execution is None:
            raise ValueError("Workflow node execution not found")

        return WorkflowRunNodeExecutionResponse.model_validate(
            workflow_node_execution, from_attributes=True
        ).model_dump(mode="json")


@console_ns.route("/rag/pipelines/<uuid:pipeline_id>/workflow-runs/tasks/<string:task_id>/stop")
class RagPipelineTaskStopApi(Resource):
    @console_ns.response(200, "Task stopped successfully", console_ns.models[SimpleResultResponse.__name__])
    @setup_required
    @login_required
    @edit_permission_required
    @rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
    @account_initialization_required
    @with_current_user
    @get_rag_pipeline
    def post(self, current_user: Account, pipeline: Pipeline, task_id: str):
        """

View on GitHub (pinned to ef8544b173)

Solutions

  1. Confirm the node_id still exists in the pipeline's current draft workflow (GET the draft graph) before invoking run.
  2. If you maintain this controller, translate the None branch to raise NotFound("Workflow node execution not found") instead of ValueError so clients get a 404.
  3. Ensure the pipeline has an initialized draft workflow; create/sync the draft before running individual nodes.
  4. Refresh the pipeline editor after graph changes so the client sends the latest node_id.

Example fix

// before
if workflow_node_execution is None:
    raise ValueError("Workflow node execution not found")
// after
from werkzeug.exceptions import NotFound
if workflow_node_execution is None:
    raise NotFound("Workflow node execution not found")
Defensive patterns

Strategy: validation

Validate before calling

// Before calling run, confirm node exists in the current draft
async function runNode(pipelineId, nodeId, inputs) {
  const draft = await fetch(`/rag/pipelines/${pipelineId}/workflows/draft`).then(r => r.json());
  const exists = JSON.stringify(draft.graph).includes(`"id":"${nodeId}"`);
  if (!exists) throw new Error(`node ${nodeId} not in draft workflow`);
  return fetch(`/rag/pipelines/${pipelineId}/workflows/draft/nodes/${nodeId}/run`, {
    method: 'POST', headers: {'Content-Type':'application/json'},
    body: JSON.stringify({ inputs })
  });
}

Type guard

function isNodeIdInGraph(graph, nodeId) {
  return Array.isArray(graph?.nodes) && graph.nodes.some(n => n.id === nodeId);
}

Try / catch

try {
  const r = await runNode(pipelineId, nodeId, inputs);
  if (!r.ok) throw await r.json();
} catch (e) {
  // 500 with 'Workflow node execution not found' -> node missing/stale
  if (e.message?.includes('Workflow node execution not found')) refreshDraft();
  else throw e;
}

Prevention

When it happens

Trigger: Calling the run-node endpoint with a node_id that does not exist in the pipeline's current draft workflow, a draft workflow that has not been initialized/synced, or a node type that the runner refuses to execute (so no execution row is persisted). The controller then hits the `if workflow_node_execution is None` branch and raises.

Common situations: Frontend 'Run single node' button pointed at a stale node_id after the graph was edited but not saved; running a node before a draft workflow exists for the pipeline; concurrent edits that drop the node; calling the API directly with a copied node_id from a different pipeline.

Related errors


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