n8n-io/n8n · error · NodeOperationError
There was an error: "The workflow did not return a response"
Error message
There was an error: "The workflow did not return a response"
What it means
Thrown by WorkflowToolService.executeSubWorkflow (v2) when, after a successful execution, the expected response slot is undefined. With returnAllItems=true it fires when receivedData.data[0] has no items; otherwise when receivedData.data[0][0].json is undefined. The tool needs a concrete payload to return.
Source
Thrown at packages/@n8n/nodes-langchain/nodes/tools/ToolWorkflow/v2/utils/WorkflowToolService.ts:285
executionId: workflowProxy.$execution.id,
workflowId: workflowProxy.$workflow.id,
},
returnLastRunOnly: true, // The tool's answer is the sub-workflow's final-run output, not its internal multi-run computation.
});
// Set sub-workflow execution id so it can be used in other places
this.subExecutionId = receivedData.executionId;
} catch (error) {
throw new NodeOperationError(context.getNode(), error as Error);
}
let response: IDataObject | INodeExecutionData[] | undefined;
if (this.returnAllItems) {
response = receivedData?.data?.[0]?.length ? receivedData.data[0] : undefined;
} else {
response = receivedData?.data?.[0]?.[0]?.json;
}
if (response === undefined) {
throw new NodeOperationError(
context.getNode(),
'There was an error: "The workflow did not return a response"',
);
}
return { response, subExecutionId: receivedData.executionId };
}
/**
* Gets the sub-workflow info based on the source and executes it.
* This function will be called as part of the tool execution (from the toolHandler)
*/
private async runFunction(
context: ISupplyDataFunctions | IExecuteFunctions,
query: string | IDataObject,
itemIndex: number,
runManager?: CallbackManagerForToolRun,
): Promise<IDataObject | INodeExecutionData[]> {View on GitHub (pinned to 5ac6606e81)
Solutions
- Open the sub-workflow and run it with the same input the agent sent; confirm output 0 emits ≥1 item.
- Add a terminal Set node that always emits a default item (e.g. { response: 'No results' }).
- If using 'Return All Items', ensure the sub-workflow's main output is a non-empty array.
- Verify the sub-workflow's last executed node isn't on a dead branch.
Example fix
// before: sub-workflow IF(false) → empty main branch → throws
// after: merge both IF branches into a single terminal Set node
// that always emits { response: {{ $json.answer || 'No results' }} } Defensive patterns
Strategy: validation
Validate before calling
const slot = this.returnAllItems ? receivedData?.data?.[0] : receivedData?.data?.[0]?.[0]?.json;
if (slot === undefined) throw new Error('Sub-workflow produced no output; add a terminal default item'); Type guard
function hasOutputItem(d: ExecuteWorkflowData, all: boolean): boolean {
return all ? (d?.data?.[0]?.length ?? 0) > 0 : d?.data?.[0]?.[0]?.json !== undefined;
} Try / catch
try { return await this.executeSubWorkflow(...); }
catch (e) { /* return a default response or rethrow with guidance */ } Prevention
- Ensure sub-workflow output 0 always has ≥1 item.
- Add a terminal default Set node for edge-case branches.
- Test the sub-workflow standalone with realistic inputs.
When it happens
Trigger: Sub-workflow runs but its terminal main-output node emits zero items; the answer lives on a non-zero run or output; returnLastRunOnly strips the run that held the data.
Common situations: Conditional sub-workflow branches that produce no output for certain inputs; sub-workflows whose final node is an error-handling branch that returns []; misconfigured output routing.
Related errors
- There was an error: "The workflow did not return a response"
- The provided workflow is not valid JSON: "${(error as Error)
- Error during parsing of JSON Schema. ${error}
- Wrong output type returned
- The provided workflow is not valid JSON: "${(error as Error)
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/775c793790848185.
Report an issue: GitHub.