From 6c9cf321addc8a167d16223737a8bff97e067bf7 Mon Sep 17 00:00:00 2001 From: viettranx Date: Sat, 11 Apr 2026 14:02:35 +0700 Subject: [PATCH] fix(store/pg): error-propagate parseUUID in kg EmbedEntity The EmbedEntity helper ran UPDATE kg_entities SET embedding = $1 WHERE id = parseUUIDOrNil(entityID). A bad UUID would resolve to uuid.Nil and the UPDATE would silently match no rows. Today's only caller passes a freshly-minted UUID, but swapping to parseUUID with an explicit Warn log closes the latent trap and aligns with the hardening policy (writes must fail fast on bad input). --- internal/store/pg/knowledge_graph_embedding.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/internal/store/pg/knowledge_graph_embedding.go b/internal/store/pg/knowledge_graph_embedding.go index 72f56824..6fec08bb 100644 --- a/internal/store/pg/knowledge_graph_embedding.go +++ b/internal/store/pg/knowledge_graph_embedding.go @@ -113,6 +113,14 @@ func (s *PGKnowledgeGraphStore) EmbedEntity(ctx context.Context, entityID, name, if s.embProvider == nil { return } + // Fail fast on a bad entity UUID so the UPDATE never degrades into a + // silent no-op WHERE id = uuid.Nil. Callers today pass a freshly minted + // UUID, but the error path guards against future drift. + eid, err := parseUUID(entityID) + if err != nil { + slog.Warn("kg entity embedding: invalid UUID", "entity_id", entityID, "error", err) + return + } text := name + " " + description embeddings, err := s.embProvider.Embed(ctx, []string{text}) if err != nil || len(embeddings) == 0 || len(embeddings[0]) == 0 { @@ -121,7 +129,7 @@ func (s *PGKnowledgeGraphStore) EmbedEntity(ctx context.Context, entityID, name, vecStr := vectorToString(embeddings[0]) if _, err := s.db.ExecContext(ctx, `UPDATE kg_entities SET embedding = $1::vector WHERE id = $2`, - vecStr, parseUUIDOrNil(entityID), + vecStr, eid, ); err != nil { slog.Warn("kg entity embedding failed", "entity_id", entityID, "error", err) }