666ghj/MiroFish · error · AssertionError
MiroFish entity context omitted incoming or outgoing node ed
Error message
MiroFish entity context omitted incoming or outgoing node edges
What it means
A hard post-run assertion inside the MiroFish Zep Cloud integration validator. After ingesting the fixture ontology, the script selects the most-connected node, computes every edge in final_edges touching that node (both source and target side), and requires ZepEntityReader.get_entity_with_context(graph_id, node_uuid) to return exactly that many related_edges. The assertion fires when the entity-context reader returns fewer (or more) edges than the graph actually contains for the selected node.
Source
Thrown at backend/scripts/validate_zep_cloud_integration.py:717
for edge in final_edges
if not edge.invalid_at and not edge.expired_at
],
"selected_node": _node_view(selected_node),
"sdk_node_edge_count": len(sdk_node_edges),
"complete_node_edge_count": len(complete_node_edges),
"entity_reader_context_edge_count": len(entity_context.related_edges),
"recent_episode_count": len(episode_list),
}
result["searches"] = {
"current_state_edges": _search_view(edge_search, final_names),
"person_nodes": _search_view(node_search, final_names),
"typed_role_edges": _search_view(typed_edge_search, final_names),
"auto_context": _search_view(auto_search, final_names),
"partnership_episodes": _search_view(episode_search, final_names),
}
if len(entity_context.related_edges) != len(complete_node_edges):
raise AssertionError(
"MiroFish entity context omitted incoming or outgoing node edges"
)
result["runtime_assertions"] = {
"edge_search_call_completed": edge_search is not None,
"node_search_call_completed": node_search is not None,
"typed_edge_search_call_completed": typed_edge_search is not None,
"auto_search_call_completed": auto_search is not None,
"episode_search_call_completed": episode_search is not None,
"node_detail_has_all_incoming_and_outgoing_edges": True,
"sdk_node_endpoint_omits_incoming_edges": (
len(sdk_node_edges) < len(complete_node_edges)
),
# The following values are observations only. Zep's extraction and
# retrieval quality are not runtime acceptance criteria.
"search_result_counts": {
"edges": len(edge_search.edges or []),
"nodes": len(node_search.nodes or []),View on GitHub (pinned to b5b53acc57)
Solutions
- Re-run the validator after a short delay: if the mismatch is indexing lag, the counts converge on the second run and no code change is needed.
- Inspect result['final'] (sdk_node_edge_count, complete_node_edge_count, entity_reader_context_edge_count) printed by the script to see whether entity_context is missing exactly the incoming edges; if so, confirm the Zep SDK/Cloud version changed behavior and pin or upgrade zep-cloud to the version the validator was written against.
- Diff the UUIDs: log [e.uuid for e in entity_context.related_edges] vs complete_node_edges to identify which edge class (expired_at/invalid_at set, custom edge name, self-loop) the reader excludes, then align the validator's complete_node_edges computation (e.g. skip edges with invalid_at/expired_at) if the reader's filtering is the intended contract.
- If Zep Cloud genuinely regressed and now omits incoming edges from entity context, file it with Zep and mark this assertion as a known-failing acceptance criterion rather than deleting it.
Example fix
// before (validator, line 716)
if len(entity_context.related_edges) != len(complete_node_edges):
raise AssertionError(
"MiroFish entity context omitted incoming or outgoing node edges"
)
# after: diagnose which edges are missing before failing
missing = {e.uuid for e in complete_node_edges} - {
e.uuid for e in entity_context.related_edges
}
if missing:
raise AssertionError(
"MiroFish entity context omitted "
f"{len(missing)} node edges: {sorted(missing)}"
) Defensive patterns
Strategy: validation
Validate before calling
# before asserting, reconcile the two edge sets and report the delta
context_uuids = {e.uuid for e in entity_context.related_edges}
expected_uuids = {e.uuid for e in complete_node_edges}
missing = expected_uuids - context_uuids
extra = context_uuids - expected_uuids
if missing or extra:
# log/diagnose instead of failing blind: indexing lag vs reader regression
print(f"missing={sorted(missing)} extra={sorted(extra)}") Type guard
from typing import Any
def has_related_edges(obj: Any) -> bool:
"""Narrow a Zep entity-context object before counting its edges."""
edges = getattr(obj, "related_edges", None)
return edges is not None and isinstance(edges, list) Try / catch
try:
run_validation(...) # executes the assertion at line 716
except AssertionError as exc:
if "omitted incoming or outgoing" not in str(exc):
raise
# tolerate transient indexing lag once, then surface diagnostics
time.sleep(10)
run_validation(...) Prevention
- Run the validator against a freshly seeded graph twice, a minute apart, before treating an edge-count mismatch as a regression.
- Pin the zep-cloud SDK version in backend requirements so reader behavior cannot drift silently.
- Keep the assertion message actionable by including both counts (entity_reader_context_edge_count vs complete_node_edge_count) at minimum.
When it happens
Trigger: Running backend/scripts/validate_zep_cloud_integration.py against a Zep Cloud graph where ZepEntityReader.get_entity_with_context omits incoming edges (edges whose target_node_uuid is the selected node), filters expired/invalidated edges differently than the validator, or the Zep backend has not yet finished indexing all edges written moments earlier. Any count mismatch, not just omission, trips it because the check uses != rather than <.
Common situations: Zep Cloud SDK version drift where the entity reader's edge filter changes; eventual-consistency lag between graph.add and graph.read right after ingestion; Zep server-side changes that stop returning incoming edges in entity context (the script already records sdk_node_endpoint_omits_incoming_edges for the raw node endpoint, which is known to omit them); fixture ontology updated with new edge types that the reader drops.
Related errors
- graph_id is required
- At least one text chunk is required
- batch_size must be between 1 and 350
- A Zep batch cannot contain more than 50,000 items
- Zep batch item exceeds 10,000 characters at chunk {oversized
AI-assisted analysis of 666ghj/MiroFish@b5b53acc57 (2026-08-14).
Data as JSON: /api/errors/047836f7aaf60df5.
Report an issue: GitHub.