diff --git a/graphiti_core/prompts/extract_edges.py b/graphiti_core/prompts/extract_edges.py
index 21f68709..de581369 100644
--- a/graphiti_core/prompts/extract_edges.py
+++ b/graphiti_core/prompts/extract_edges.py
@@ -24,8 +24,12 @@ from .prompt_helpers import to_prompt_json
class Edge(BaseModel):
relation_type: str = Field(..., description='FACT_PREDICATE_IN_SCREAMING_SNAKE_CASE')
- source_entity_id: int = Field(..., description='The id of the source entity of the fact.')
- target_entity_id: int = Field(..., description='The id of the target entity of the fact.')
+ source_entity_id: int = Field(
+ ..., description='The id of the source entity from the ENTITIES list'
+ )
+ target_entity_id: int = Field(
+ ..., description='The id of the target entity from the ENTITIES list'
+ )
fact: str = Field(..., description='')
valid_at: str | None = Field(
None,
@@ -81,7 +85,7 @@ def edge(context: dict[str, Any]) -> list[Message]:
-{context['nodes']}
+{to_prompt_json(context['nodes'], ensure_ascii=context.get('ensure_ascii', False), indent=2)}
@@ -107,7 +111,8 @@ You may use information from the PREVIOUS MESSAGES only to disambiguate referenc
# EXTRACTION RULES
-1. Only emit facts where both the subject and object match IDs in ENTITIES.
+1. **Entity ID Validation**: `source_entity_id` and `target_entity_id` must use only the `id` values from the ENTITIES list provided above.
+ - **CRITICAL**: Using IDs not in the list will cause the edge to be rejected
2. Each fact must involve two **distinct** entities.
3. Use a SCREAMING_SNAKE_CASE string as the `relation_type` (e.g., FOUNDED, WORKS_AT).
4. Do not emit duplicate or semantically redundant facts.
diff --git a/graphiti_core/utils/maintenance/edge_operations.py b/graphiti_core/utils/maintenance/edge_operations.py
index a6760a40..a15a93de 100644
--- a/graphiti_core/utils/maintenance/edge_operations.py
+++ b/graphiti_core/utils/maintenance/edge_operations.py
@@ -181,7 +181,9 @@ async def extract_edges(
target_node_idx = edge_data.target_entity_id
if not (-1 < source_node_idx < len(nodes) and -1 < target_node_idx < len(nodes)):
logger.warning(
- f'WARNING: source or target node not filled {edge_data.relation_type}. source_node_uuid: {source_node_idx} and target_node_uuid: {target_node_idx} '
+ f'Invalid entity IDs in edge extraction for {edge_data.relation_type}. '
+ f'source_entity_id: {source_node_idx}, target_entity_id: {target_node_idx}, '
+ f'but only {len(nodes)} entities available (valid range: 0-{len(nodes) - 1})'
)
continue
source_node_uuid = nodes[source_node_idx].uuid