affaan-m/ECC · warning · anyhow::Error
Context graph entity name cannot be empty
Error message
Context graph entity name cannot be empty
What it means
Raised by upsert_context_entity in ecc2/src/session/store.rs:3103 when name.trim().is_empty(). The name, together with entity_type and optional path, forms the entity_key via context_graph_entity_key; an empty name would produce ambiguous keys and break lookups, so it is rejected before insert.
Source
Thrown at ecc2/src/session/store.rs:3103
Ok(stats)
}
pub fn upsert_context_entity(
&self,
session_id: Option<&str>,
entity_type: &str,
name: &str,
path: Option<&str>,
summary: &str,
metadata: &BTreeMap<String, String>,
) -> Result<ContextGraphEntity> {
let entity_type = entity_type.trim();
if entity_type.is_empty() {
return Err(anyhow::anyhow!("Context graph entity type cannot be empty"));
}
let name = name.trim();
if name.is_empty() {
return Err(anyhow::anyhow!("Context graph entity name cannot be empty"));
}
let normalized_path = path.map(str::trim).filter(|value| !value.is_empty());
let summary = summary.trim();
let entity_key = context_graph_entity_key(entity_type, name, normalized_path);
let metadata_json = serde_json::to_string(metadata)
.context("Failed to serialize context graph metadata")?;
let timestamp = chrono::Utc::now().to_rfc3339();
self.conn.execute(
"INSERT INTO context_graph_entities (
session_id, entity_key, entity_type, name, path, summary, metadata_json, created_at, updated_at
)
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?8)
ON CONFLICT(entity_key) DO UPDATE SET
session_id = COALESCE(excluded.session_id, context_graph_entities.session_id),
summary = CASE
WHEN excluded.summary <> '' THEN excluded.summaryView on GitHub (pinned to 01e15490f0)
Solutions
- Validate name at the call site: require non-empty after trim; if name is derived from a path, fall back to the path string or skip the record.
- During import, drop or quarantine rows with empty names.
- Co-locate validation so upsert_context_entity never receives empty names.
Example fix
// before
let name = path.file_name().map(|s| s.to_string_lossy().to_string()).unwrap_or_default();
store.upsert_context_entity(None, etype, &name, Some(&path), summary, &meta)?;
// after: guard the derived name
let name = path.file_name()
.map(|s| s.to_string_lossy().to_string())
.unwrap_or_else(|| path.to_string_lossy().to_string());
if name.trim().is_empty() {
anyhow::bail!("cannot derive a non-empty entity name from {path}");
}
store.upsert_context_entity(None, etype, &name, Some(&path), summary, &meta)?; Defensive patterns
Strategy: validation
Validate before calling
// Same newtype pattern for the name.
#[derive(Debug, Clone)]
pub struct ContextEntityName(String);
impl ContextEntityName {
pub fn new(raw: &str) -> anyhow::Result<Self> {
let trimmed = raw.trim();
if trimmed.is_empty() {
anyhow::bail!("context graph entity name cannot be empty");
}
Ok(Self(trimmed.to_string()))
}
pub fn as_str(&self) -> &str { &self.0 }
}
// When deriving name from a path, fall back to the path string itself.
fn name_from_path(path: &Path) -> anyhow::Result<ContextEntityName> {
let raw = path.file_name()
.map(|s| s.to_string_lossy().to_string())
.unwrap_or_else(|| path.to_string_lossy().to_string());
ContextEntityName::new(&raw)
} Type guard
// ContextEntityName (above) is the type guard: it cannot represent an // empty string.
Try / catch
for record in import_stream {
let name = match ContextEntityName::new(&record.name) {
Ok(n) => n,
Err(_) => { tracing::warn!("skipping entity with empty name"); continue; }
};
store.upsert_context_entity(sid, etype, name.as_str(), path, summary, &meta)?;
} Prevention
- Wrap entity name in a validating newtype.
- When deriving from a path, fall back to the full path string if the basename is empty.
- Skip blank-name records during import.
- Require a non-empty name at the UI layer.
When it happens
Trigger: Passing an empty or whitespace-only name; a caller that builds name from a filename whose basename is empty; importing entities where the name column is blank.
Common situations: Bulk import with sparse data; deriving name from Path::file_name() on a path ending in '/' (returns None -> ""); UI input not validated.
Related errors
- Context graph entity type cannot be empty
- Context graph observation type cannot be empty
- Context graph observation summary cannot be empty
- Context graph relation type cannot be empty
- Context graph entity not found: {entity_id}
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/95a4c32a62fba1ed.
Report an issue: GitHub.