{"record":{"id":"4ab094d16b78011a","repo":"vxcontrol/pentagi","slug":"knowledge-list-all-w","errorCode":null,"errorMessage":"knowledge: list all: %w","messagePattern":"knowledge: list all: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/pkg/database/knowledge/knowledge.go","lineNumber":267,"sourceCode":"}\n\n// ---- ListDocuments (admin) --------------------------------------------------\n\nfunc (ks *knowledgeStore) ListDocuments(ctx context.Context, filter *model.KnowledgeFilter, withContent bool) ([]*model.KnowledgeDocument, error) {\n\tvar docs []*model.KnowledgeDocument\n\n\tif filter != nil && filter.FlowID != nil {\n\t\trows, err := ks.db.ListFlowKnowledgeDocuments(ctx, nsOf(strconv.FormatInt(*filter.FlowID, 10)))\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"knowledge: list by flow: %w\", err)\n\t\t}\n\t\tfor _, r := range rows {\n\t\t\tdocs = append(docs, rowToModel(r.ID, r.Document, nullStr(r.Cmetadata), withContent))\n\t\t}\n\t} else {\n\t\trows, err := ks.db.ListAllKnowledgeDocuments(ctx)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"knowledge: list all: %w\", err)\n\t\t}\n\t\tfor _, r := range rows {\n\t\t\tdocs = append(docs, rowToModel(r.ID, r.Document, nullStr(r.Cmetadata), withContent))\n\t\t}\n\t}\n\n\treturn applyGoFilters(docs, filter), nil\n}\n\n// ---- ListUserDocuments (user-scoped) ----------------------------------------\n\nfunc (ks *knowledgeStore) ListUserDocuments(ctx context.Context, userID int64, filter *model.KnowledgeFilter, withContent bool) ([]*model.KnowledgeDocument, error) {\n\tuserIDStr := strconv.FormatInt(userID, 10)\n\tvar docs []*model.KnowledgeDocument\n\n\tif filter != nil && filter.FlowID != nil {\n\t\t// Flow-scoped listing; user_id check applied in Go for safety.\n\t\trows, err := ks.db.ListFlowKnowledgeDocuments(ctx, nsOf(strconv.FormatInt(*filter.FlowID, 10)))","sourceCodeStart":249,"sourceCodeEnd":285,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/database/knowledge/knowledge.go#L249-L285","documentation":"The same ListDocuments flow, but for the branch where no FlowID filter is set: it wraps failures of ListAllKnowledgeDocuments — listing every knowledge document across all flows — as \"knowledge: list all: %w\". Root causes are database-level: connectivity, timeout, or extension/SQL errors on the full-table scan.","triggerScenarios":"Calling ListDocuments(ctx, nil filter or filter without FlowID, withContent) when PostgreSQL is unreachable, the full listing times out under a large table, or the pgvector/JSONB metadata columns error during scan.","commonSituations":"Admin UI listing all knowledge documents on a large deployment; database under heavy load; metadata column schema drift after a manual migration; connection pool exhaustion.","solutions":["Unwrap the driver error and check PostgreSQL server logs.","Prefer flow-scoped listing (set filter.FlowID) to avoid the unbounded full scan.","Add pagination/LIMIT to ListAllKnowledgeDocuments for large tables.","Verify DB connectivity and the pgvector extension state.","Increase statement timeout or optimize indexes if the scan legitimately needs to run."],"exampleFix":"// before\ndocs, err := kStore.ListDocuments(ctx, nil, true)\n// after\nfilter := &model.KnowledgeFilter{FlowID: &flowID} // scope instead of listing all\ndocs, err := kStore.ListDocuments(ctx, filter, true)\nif err != nil { return fmt.Errorf(\"list docs: %w\", err) }","handlingStrategy":"validation","validationCode":"// avoid unbounded listing when possible\nif filter == nil || filter.FlowID == nil {\n    if !allowFullKnowledgeScan {\n        return fmt.Errorf(\"refusing unbounded knowledge listing; set FlowID filter\")\n    }\n}\nif err := ctx.Err(); err != nil {\n    return nil, err\n}","typeGuard":"func isQueryTimeout(err error) bool {\n    var pgErr *pgconn.PgError\n    return errors.As(err, &pgErr) && pgErr.Code == \"57014\"\n}","tryCatchPattern":"docs, err := kStore.ListDocuments(ctx, nil, withContent)\nif err != nil {\n    if isQueryTimeout(err) {\n        return listAllInBatches(ctx, kStore, withContent) // chunked fallback\n    }\n    return nil, fmt.Errorf(\"knowledge list all: %w\", err)\n}","preventionTips":["Prefer flow-scoped filters over ListAllKnowledgeDocuments on large deployments.","Add pagination to the admin listing endpoint.","Index the knowledge table appropriately and vacuum regularly.","Watch for pgvector extension errors after version upgrades."],"tags":["go","database","postgres","pgvector","query-failed"],"backgroundTag":"database-query-failed","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}