vxcontrol/pentagi · error

knowledge: list by flow (user): %w

Error message

knowledge: list by flow (user): %w

What it means

ListUserDocuments mirrors ListDocuments but additionally filters rows in Go by user_id parsed from document metadata. When the flow-scoped query (ListFlowKnowledgeDocuments) fails, the error is wrapped as "knowledge: list by flow (user): %w". The cause is the underlying DB query, not the user filtering.

Source

Thrown at backend/pkg/database/knowledge/knowledge.go:287

		for _, r := range rows {
			docs = append(docs, rowToModel(r.ID, r.Document, nullStr(r.Cmetadata), withContent))
		}
	}

	return applyGoFilters(docs, filter), nil
}

// ---- ListUserDocuments (user-scoped) ----------------------------------------

func (ks *knowledgeStore) ListUserDocuments(ctx context.Context, userID int64, filter *model.KnowledgeFilter, withContent bool) ([]*model.KnowledgeDocument, error) {
	userIDStr := strconv.FormatInt(userID, 10)
	var docs []*model.KnowledgeDocument

	if filter != nil && filter.FlowID != nil {
		// Flow-scoped listing; user_id check applied in Go for safety.
		rows, err := ks.db.ListFlowKnowledgeDocuments(ctx, nsOf(strconv.FormatInt(*filter.FlowID, 10)))
		if err != nil {
			return nil, fmt.Errorf("knowledge: list by flow (user): %w", err)
		}
		for _, r := range rows {
			meta := parseMeta(nullStr(r.Cmetadata))
			if strconv.FormatInt(meta.UserID, 10) != userIDStr {
				continue
			}
			docs = append(docs, rowToModel(r.ID, r.Document, nullStr(r.Cmetadata), withContent))
		}
	} else {
		rows, err := ks.db.ListUserKnowledgeDocuments(ctx, nsOf(userIDStr))
		if err != nil {
			return nil, fmt.Errorf("knowledge: list user docs: %w", err)
		}
		for _, r := range rows {
			docs = append(docs, rowToModel(r.ID, r.Document, nullStr(r.Cmetadata), withContent))
		}
	}

View on GitHub (pinned to ea665308ba)

Solutions

  1. Unwrap and inspect the wrapped DB error; check PostgreSQL logs.
  2. Verify database connectivity and pgvector extension health.
  3. Ensure knowledge documents carry user_id in metadata (re-index legacy documents) so per-user filtering works.
  4. Scope or paginate the query if the flow has many documents.
  5. Retry transient connection failures with backoff.

Example fix

// before
rows, err := ks.db.ListFlowKnowledgeDocuments(ctx, ns)
if err != nil {
    return nil, fmt.Errorf("knowledge: list by flow (user): %w", err)
}
// after
rows, err := ks.db.ListFlowKnowledgeDocuments(ctx, ns)
if err != nil {
    if errors.Is(err, context.DeadlineExceeded) {
        return nil, ErrKnowledgeListTimeout
    }
    return nil, fmt.Errorf("knowledge: list by flow (user): %w", err)
}
Defensive patterns

Strategy: retry

Validate before calling

if userID == "" || filter == nil || filter.FlowID == nil || *filter.FlowID <= 0 {
    return fmt.Errorf("user listing requires userID and valid FlowID")
}
if err := ctx.Err(); err != nil {
    return nil, err
}

Type guard

func isDBConnError(err error) bool {
    var pgErr *pgconn.PgError
    return errors.As(err, &pgErr) && (pgErr.Code == "08006" || pgErr.Code == "08003") ||
        errors.Is(err, context.DeadlineExceeded)
}

Try / catch

docs, err := kStore.ListUserDocuments(ctx, userID, filter, withContent)
if err != nil {
    if isDBConnError(err) {
        docs, err = retryWithBackoff(3, func() ([]*model.KnowledgeDocument, error) {
            return kStore.ListUserDocuments(ctx, userID, filter, withContent)
        })
    }
    if err != nil { return nil, fmt.Errorf("user knowledge list: %w", err) }
}

Prevention

When it happens

Trigger: Calling ListUserDocuments(ctx, userID, filter with FlowID, withContent) when the flow-scoped pgvector query fails: DB unreachable, timeout, extension error, or malformed metadata that breaks downstream parsing (error surfaces here first as a query failure).

Common situations: User-facing knowledge listing for a flow whose DB connection dropped; metadata written by older versions lacking user_id (causes empty results or downstream parse issues); pool exhaustion; pgvector upgrade mismatches.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01). Data as JSON: /api/errors/b3d7fd0d90219b93. Report an issue: GitHub.