From 642603e14ebc5c2395d05883a11ed4bfcda79426 Mon Sep 17 00:00:00 2001 From: viettranx Date: Sat, 11 Apr 2026 11:39:08 +0700 Subject: [PATCH] refactor(store/pg): error-propagate parseUUID in memory_docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 5 CRITICAL sites migrated from mustParseUUID to parseUUID with wrapped errors: GetDocument, PutDocument, DeleteDocument, ListDocuments, IndexDocument. All handle bad agent_id input at the caller boundary instead of hitting FK violation (writes) or returning empty results (reads). Scout classified GetDocument as both CRITICAL and WARN — migrating all 5 is safer and consistent (M8 note). Phase 4 Step 4b.2 of agent identity hardening (TD-1). --- internal/store/pg/memory_docs.go | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/internal/store/pg/memory_docs.go b/internal/store/pg/memory_docs.go index 2b1c6037..80207b8e 100644 --- a/internal/store/pg/memory_docs.go +++ b/internal/store/pg/memory_docs.go @@ -47,10 +47,12 @@ func NewPGMemoryStore(db *sql.DB, cfg PGMemoryConfig) *PGMemoryStore { } func (s *PGMemoryStore) GetDocument(ctx context.Context, agentID, userID, path string) (string, error) { - aid := mustParseUUID(agentID) + aid, err := parseUUID(agentID) + if err != nil { + return "", fmt.Errorf("memory get document: %w", err) + } var content string - var err error if store.IsSharedMemory(ctx) { // Shared: no user_id filter tc, tcArgs, _, tcErr := scopeClause(ctx, 3) @@ -84,7 +86,10 @@ func (s *PGMemoryStore) GetDocument(ctx context.Context, agentID, userID, path s } func (s *PGMemoryStore) PutDocument(ctx context.Context, agentID, userID, path, content string) error { - aid := mustParseUUID(agentID) + aid, err := parseUUID(agentID) + if err != nil { + return fmt.Errorf("memory put document: %w", err) + } hash := memory.ContentHash(content) id := uuid.Must(uuid.NewV7()) now := time.Now() @@ -95,7 +100,7 @@ func (s *PGMemoryStore) PutDocument(ctx context.Context, agentID, userID, path, uid = &userID } - _, err := s.db.ExecContext(ctx, + _, err = s.db.ExecContext(ctx, `INSERT INTO memory_documents (id, agent_id, user_id, path, content, hash, tenant_id, updated_at) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) ON CONFLICT (agent_id, COALESCE(user_id, ''), path) @@ -106,9 +111,11 @@ func (s *PGMemoryStore) PutDocument(ctx context.Context, agentID, userID, path, } func (s *PGMemoryStore) DeleteDocument(ctx context.Context, agentID, userID, path string) error { - aid := mustParseUUID(agentID) + aid, err := parseUUID(agentID) + if err != nil { + return fmt.Errorf("memory delete document: %w", err) + } var res sql.Result - var err error if store.IsSharedMemory(ctx) { // Shared: delete any matching doc regardless of user_id tc, tcArgs, _, tcErr := scopeClause(ctx, 3) @@ -146,7 +153,10 @@ func (s *PGMemoryStore) DeleteDocument(ctx context.Context, agentID, userID, pat } func (s *PGMemoryStore) ListDocuments(ctx context.Context, agentID, userID string) ([]store.DocumentInfo, error) { - aid := mustParseUUID(agentID) + aid, err := parseUUID(agentID) + if err != nil { + return nil, fmt.Errorf("memory list documents: %w", err) + } var q string var args []any @@ -187,7 +197,10 @@ func (s *PGMemoryStore) ListDocuments(ctx context.Context, agentID, userID strin // IndexDocument chunks a document and stores chunks with embeddings. func (s *PGMemoryStore) IndexDocument(ctx context.Context, agentID, userID, path string) error { - aid := mustParseUUID(agentID) + aid, err := parseUUID(agentID) + if err != nil { + return fmt.Errorf("memory index document: %w", err) + } // Get document content content, err := s.GetDocument(ctx, agentID, userID, path)