{"record":{"id":"95a4c32a62fba1ed","repo":"affaan-m/ECC","slug":"context-graph-entity-name-cannot-be-empty","errorCode":null,"errorMessage":"Context graph entity name cannot be empty","messagePattern":"Context graph entity name cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ecc2/src/session/store.rs","lineNumber":3103,"sourceCode":"        Ok(stats)\n    }\n\n    pub fn upsert_context_entity(\n        &self,\n        session_id: Option<&str>,\n        entity_type: &str,\n        name: &str,\n        path: Option<&str>,\n        summary: &str,\n        metadata: &BTreeMap<String, String>,\n    ) -> Result<ContextGraphEntity> {\n        let entity_type = entity_type.trim();\n        if entity_type.is_empty() {\n            return Err(anyhow::anyhow!(\"Context graph entity type cannot be empty\"));\n        }\n        let name = name.trim();\n        if name.is_empty() {\n            return Err(anyhow::anyhow!(\"Context graph entity name cannot be empty\"));\n        }\n\n        let normalized_path = path.map(str::trim).filter(|value| !value.is_empty());\n        let summary = summary.trim();\n        let entity_key = context_graph_entity_key(entity_type, name, normalized_path);\n        let metadata_json = serde_json::to_string(metadata)\n            .context(\"Failed to serialize context graph metadata\")?;\n        let timestamp = chrono::Utc::now().to_rfc3339();\n\n        self.conn.execute(\n            \"INSERT INTO context_graph_entities (\n                session_id, entity_key, entity_type, name, path, summary, metadata_json, created_at, updated_at\n             )\n             VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?8)\n             ON CONFLICT(entity_key) DO UPDATE SET\n                session_id = COALESCE(excluded.session_id, context_graph_entities.session_id),\n                summary = CASE\n                    WHEN excluded.summary <> '' THEN excluded.summary","sourceCodeStart":3085,"sourceCodeEnd":3121,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/ecc2/src/session/store.rs#L3085-L3121","documentation":"Companion to the entity-type check: after trimming, an empty name produces `Context graph entity name cannot be empty`. The name, together with type and normalized path, forms the entity key, so an empty name would create an invalid key.","triggerScenarios":"upsert_context_graph_entity called with name = \"\" or whitespace — e.g. extracting an entity label from parsed content that yielded an empty match, or a caller defaulting name to String::new().","commonSituations":"Regex/AST extraction returning empty capture groups; spreadsheet/CSV imports with blank name cells; UI forms submitted without the name field.","solutions":["Ensure the caller supplies a non-empty name; skip entities with blank labels.","Validate extraction output (reject empty capture groups) before persisting.","Make the name required at the API boundary (Option or constructor validation) so empty values never reach the store.","Normalize/trim the name upstream and fall back to a placeholder only when semantically valid."],"exampleFix":"// before\nlet name = captures.get(1).map(|m| m.as_str()).unwrap_or(\"\");\nstore.upsert_context_graph_entity(entity_type, name, path, &summary, &meta)?;\n// after\nif let Some(m) = captures.get(1).filter(|m| !m.as_str().trim().is_empty()) {\n    store.upsert_context_graph_entity(entity_type, m.as_str().trim(), path, &summary, &meta)?;\n}","handlingStrategy":"validation","validationCode":"const n = name.trim();\nif (!n) return; // skip blank entities\nawait api.upsertContextGraphEntity(entityType, n, path, summary, metadata);","typeGuard":"function hasName(v) { return typeof v === 'string' && v.trim().length > 0; }","tryCatchPattern":"try {\n    store.upsert_context_graph_entity(&etype, &name, path, &summary, &meta)?;\n} catch (e) {\n    if (String(e).includes('entity name cannot be empty')) {\n        log::debug!(\"dropped entity with empty name\");\n    } else throw e;\n}","preventionTips":["Reject empty capture groups from extraction regexes before persisting.","Trim names at every ingestion boundary.","Make the name field required in forms/DTOs so blanks never reach the store.","Log skipped entities with their source to find producers emitting blanks."],"tags":["context-graph","validation","empty-field"],"backgroundTag":"empty-required-field","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}