refactor(store/pg): error-propagate parseUUID in memory_docs

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).
This commit is contained in:
viettranx committed 2026-04-11 21:22:23 +07:00
1 parent 32af80b28c
commit 642603e14e
1 file changed
+21 -8
+21 -8
View File
@@ -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)