Health: a flow that cannot run says so, and the brain marks which neurons
A dependency loop is flagged on the canvas and was invisible everywhere else: /observability/summary answered "ok" with an empty problems list while the published flow could not run at all. It now reports the flows validation blocks, and the brain graph carries the reason on each neuron the issue names so the view built to find broken wiring can show it. Node errors stay counted once, as the nodes that failed to load, and an advisory like an unauthenticated webhook marks nothing — it is worth saying, but the flow still runs. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XC2jX6Hdj7pxGGKzBTrbqB
This commit is contained in:
@@ -17,7 +17,7 @@ from sqlalchemy import func
|
||||
from sqlmodel import col, select
|
||||
|
||||
from app.api.deps import FlowControllerDep, SessionDep, get_current_user
|
||||
from app.flow.controller import NodeStatus
|
||||
from app.flow.controller import ADVISORY_ISSUES, NodeStatus
|
||||
from app.models import EngineEvent, FlowRun, MetricBucket
|
||||
|
||||
router = APIRouter(
|
||||
@@ -128,6 +128,22 @@ async def read_summary(
|
||||
if errored:
|
||||
problems.append(f"{len(errored)} node(s) failed to load")
|
||||
|
||||
# What the canvas flags on a flow — a dependency loop, an input nothing
|
||||
# feeds — stops that flow running just as surely as a node that will not
|
||||
# load, and until now this screen was the one place it did not show.
|
||||
# `node_error` is left out: those are the nodes already counted above.
|
||||
invalid = sorted(
|
||||
{
|
||||
issue.flow
|
||||
for issue in controller.issues
|
||||
if issue.flow
|
||||
and issue.code != "node_error"
|
||||
and issue.code not in ADVISORY_ISSUES
|
||||
}
|
||||
)
|
||||
if invalid:
|
||||
problems.append(f"{len(invalid)} flow(s) cannot run: {', '.join(invalid)}")
|
||||
|
||||
statement = (
|
||||
select(func.count())
|
||||
.select_from(EngineEvent)
|
||||
@@ -146,6 +162,7 @@ async def read_summary(
|
||||
),
|
||||
"paused": len(paused),
|
||||
"quarantined": len(quarantined),
|
||||
"invalid": len(invalid),
|
||||
},
|
||||
nodes={"total": len(entries), "error": len(errored)},
|
||||
queue=queue,
|
||||
|
||||
Reference in New Issue
Block a user