affaan-m/ECC · error
Context graph relation type cannot be empty
Error message
Context graph relation type cannot be empty
What it means
When linking two entities, the relation write path trims relation_type and rejects empties with `Context graph relation type cannot be empty`. The relation type labels the edge (e.g. "depends_on", "references") and is required for meaningful graph traversal.
Solutions
- Pass a concrete relation type string for each edge creation site.
- Map unknown analyzer kinds to an explicit "related" fallback instead of empty.
- Trim/validate relation_type before calling; skip edges without a label.
- Grep for relation-creation call sites to catch any passing a possibly-empty variable.
Example fix
// before
store.add_context_graph_relation(from_id, to_id, &edge_label, &summary)?;
// after
let rel = edge_label.trim();
if !rel.is_empty() {
store.add_context_graph_relation(from_id, to_id, rel, &summary)?;
} Defensive patterns
Strategy: validation
Validate before calling
const rel = relationType.trim(); if (!rel) return; // unlabeled edge: skip await api.addContextGraphRelation(fromId, toId, rel, summary);
Type guard
function hasRelationType(v) { return typeof v === 'string' && v.trim().length > 0; } Try / catch
try {
store.add_context_graph_relation(from_id, to_id, &rel, &summary)?;
} catch (e) {
if (String(e).includes('relation type cannot be empty')) {
store.add_context_graph_relation(from_id, to_id, "related", &summary)?;
} else throw e;
} Prevention
- Maintain a whitelist of valid relation types and map unknowns to a fallback.
- Grep all relation-creation call sites for possibly-empty label variables.
- Use a newtype or enum for RelationType to make empty values unrepresentable.
- Add boundary validation tests for blank relation labels.
When it happens
Trigger: Calling the relation API with relation_type = "" or whitespace — commonly when the edge label comes from a mapping table or analyzer output that returned nothing.
Common situations: Dependency analyzers with unmapped relationship kinds; generic graph importers where the edge label column is blank; refactors that renamed a relation constant but left one call site defaulting to empty.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Context graph entity name cannot be empty
- Context graph entity type cannot be empty
- Context graph observation summary cannot be empty
- Context graph observation type cannot be empty
- -32602
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/cc36d3499860073e.
Report an issue: GitHub.
Appendix: source
Thrown at ecc2/src/session/store.rs:3673
Ok(ContextGraphCompactionStats {
entities_scanned,
duplicate_observations_deleted,
overflow_observations_deleted,
observations_retained,
})
}
pub fn upsert_context_relation(
&self,
session_id: Option<&str>,
from_entity_id: i64,
to_entity_id: i64,
relation_type: &str,
summary: &str,
) -> Result<ContextGraphRelation> {
let relation_type = relation_type.trim();
if relation_type.is_empty() {
return Err(anyhow::anyhow!(
"Context graph relation type cannot be empty"
));
}
let summary = summary.trim();
let timestamp = chrono::Utc::now().to_rfc3339();
self.conn.execute(
"INSERT INTO context_graph_relations (
session_id, from_entity_id, to_entity_id, relation_type, summary, created_at
)
VALUES (?1, ?2, ?3, ?4, ?5, ?6)
ON CONFLICT(from_entity_id, to_entity_id, relation_type) DO UPDATE SET
session_id = COALESCE(excluded.session_id, context_graph_relations.session_id),
summary = CASE
WHEN excluded.summary <> '' THEN excluded.summary
ELSE context_graph_relations.summary
END",
rusqlite::params![View on GitHub (pinned to 8321021c54)