Skip to content

Commit b464e69

Browse files
committed
Prevent false green validation results when MCP build streams end early
validate_flow already tracked how many nodes were expected, but the final success path only checked whether a failing event had been seen. An early end event could therefore return valid=true even when only part of the flow finished. This change treats that condition as invalid and records a flow-level error, while keeping the existing fast-fail behavior unchanged. Constraint: Keep the fix narrowly scoped to validate_flow rather than folding it into broader MCP/session work Rejected: Wait for PR langflow-ai#12528 to land | it does not close this exact success-path gap on current main Confidence: high Scope-risk: narrow Reversibility: clean Directive: If validate_flow semantics change again, preserve the invariant that success means every expected component completed Tested: cd src/lfx && uv sync && uv run pytest tests/unit/mcp/test_validate_flow.py -q Not-tested: End-to-end MCP validation against a live Langflow server Related: langflow-ai#12757
1 parent 9aae6de commit b464e69

2 files changed

Lines changed: 30 additions & 0 deletions

File tree

src/lfx/src/lfx/mcp/server.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1145,6 +1145,18 @@ async def validate_flow(flow_id: str) -> dict[str, Any]:
11451145
"errors": errors,
11461146
}
11471147

1148+
if len(completed) != expected:
1149+
return {
1150+
"valid": False,
1151+
"component_count": len(completed),
1152+
"errors": [
1153+
{
1154+
"component_id": "flow",
1155+
"error": f"Build ended early: {len(completed)}/{expected} components completed",
1156+
}
1157+
],
1158+
}
1159+
11481160
return {
11491161
"valid": True,
11501162
"component_count": len(completed),

src/lfx/tests/unit/mcp/test_validate_flow.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,3 +162,21 @@ async def _stream(*_args, **_kwargs):
162162
assert result["valid"] is False
163163
assert "Build request failed" in result["error"]
164164
assert result["component_count"] == 0
165+
166+
async def test_end_event_before_all_components_finish_returns_failure(self) -> None:
167+
"""An early end event must not be reported as a valid full build."""
168+
from lfx.mcp.server import validate_flow
169+
170+
flow = _flow_with_nodes(2)
171+
events = [
172+
_end_vertex_event("A-1", valid=True),
173+
_end_event(),
174+
]
175+
client = _stream_client(events)
176+
177+
with _patch_validate(flow=flow, client=client):
178+
result = await validate_flow("flow-1")
179+
180+
assert result["valid"] is False
181+
assert result["component_count"] == 1
182+
assert result["errors"] == [{"component_id": "flow", "error": "Build ended early: 1/2 components completed"}]

0 commit comments

Comments
 (0)