nocobase/nocobase · error · Error
head node not found in workflow (#${this.execution.workflowI
Error message
head node not found in workflow (#${this.execution.workflowId}) What it means
When rerun is called without an explicit nodeId, getRerunNode derives the rerun start point from the workflow's head node (the node with no upstream). If no such node exists — the workflow graph is cyclic or has multiple disconnected entry nodes — it throws because rerun cannot determine where to start.
Source
Thrown at packages/plugins/@nocobase/plugin-workflow/src/server/Processor.ts:387
return await this.run(node, input, { rerun: true });
} finally {
this.rerunContext = null;
this.leaveRunningState();
}
}
private getRerunNode(nodeId?: string | number) {
if (nodeId != null) {
const node = this.nodesMap.get(nodeId) || this.nodes.find((item) => String(item.id) === String(nodeId));
if (!node) {
throw new Error(`node (#${nodeId}) not found in workflow (#${this.execution.workflowId})`);
}
return node;
}
const head = this.nodes.find((item) => !item.upstream);
if (!head) {
throw new Error(`head node not found in workflow (#${this.execution.workflowId})`);
}
return head;
}
private getRerunInput(node: FlowNodeModel) {
if (!node.upstream) {
return { result: this.execution.context };
}
const upstreamJob = this.jobsMapByNodeKey[node.upstream.key];
if (!upstreamJob) {
throw new Error(`upstream job of node (#${node.id}) not found in execution (#${this.execution.id})`);
}
return upstreamJob;
}
private async exec(View on GitHub (pinned to fa42722fef)
Solutions
- Inspect flow_nodes for the workflow: exactly one node should have upstreamId null; fix broken upstreamId values.
- Call rerun with an explicit valid nodeId instead of relying on head detection.
- Rebuild/duplicate the workflow in the UI if its graph is corrupted.
- Verify nodes loaded (execution.workflow.nodes non-empty) before rerunning.
Example fix
// before
await processor.rerun({});
// after
const head = execution.workflow.nodes.find((n) => !n.upstream);
if (!head) {
console.error(`workflow ${execution.workflowId} has no head node; fix node graph`);
} else {
await processor.rerun({ nodeId: head.id });
} Defensive patterns
Strategy: validation
Validate before calling
const nodes = await workflow.getNodes();
const head = nodes.find((n) => !n.upstream);
if (!head) {
throw new Error(`workflow ${workflow.id} graph is corrupted: no head node (check flow_nodes.upstreamId for cycles)`);
} Type guard
function hasSingleHead(nodes: FlowNodeModel[]): boolean {
return nodes.filter((n) => !n.upstream).length === 1;
} Try / catch
try {
await processor.rerun({});
} catch (e) {
if (/head node not found/.test(e.message)) {
logger.error(`workflow ${execution.workflowId} has no head node; repair graph or pass explicit nodeId`);
return null;
}
throw e;
} Prevention
- Never edit flow_nodes.upstreamId directly; use the workflow canvas so invariants hold.
- Assert every workflow has exactly one upstream-less node after import/copy.
- If the graph is uncertain, always pass an explicit nodeId to rerun.
- Add a lint/audit script that detects cycles and missing heads in stored workflows.
When it happens
Trigger: processor.rerun({}) on a workflow whose node list contains no node with item.upstream falsy — corrupted node graph, all nodes have upstream links (cycle), or nodes failed to load so the list is incomplete/empty.
Common situations: Manually edited workflow node relationships creating a cycle; import/copy of a workflow losing the head node; data corruption in flow_nodes.upstreamId; rerunning an execution whose workflow nodes were never loaded (nodes array empty in this pass).
Related errors
- job of node (#${node.id}) not found in execution (#${this.ex
- job of head node (#${node.id}) not found in execution (#${th
- execution (#${execution.id}) is not started
- node (#${nodeId}) not found in workflow (#${this.execution.w
- upstream job of node (#${node.id}) not found in execution (#
AI-assisted analysis of nocobase/nocobase@fa42722fef (2026-09-01).
Data as JSON: /api/errors/586c33efa441d097.
Report an issue: GitHub.