{"record":{"id":"b12bf7744f62b4e9","repo":"vxcontrol/pentagi","slug":"knowledge-list-user-docs-w","errorCode":null,"errorMessage":"knowledge: list user docs: %w","messagePattern":"knowledge: list user docs: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/pkg/database/knowledge/knowledge.go","lineNumber":299,"sourceCode":"\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)))\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"knowledge: list by flow (user): %w\", err)\n\t\t}\n\t\tfor _, r := range rows {\n\t\t\tmeta := parseMeta(nullStr(r.Cmetadata))\n\t\t\tif strconv.FormatInt(meta.UserID, 10) != userIDStr {\n\t\t\t\tcontinue\n\t\t\t}\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.ListUserKnowledgeDocuments(ctx, nsOf(userIDStr))\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"knowledge: list user docs: %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// ---- GetDocument (admin) ----------------------------------------------------\n\nfunc (ks *knowledgeStore) GetDocument(ctx context.Context, id string) (*model.KnowledgeDocument, error) {\n\trow, err := ks.db.GetKnowledgeDocument(ctx, id)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"knowledge: get document %s: %w\", id, err)\n\t}\n\treturn rowToModel(row.ID, row.Document, nullStr(row.Cmetadata), true), nil\n}","sourceCodeStart":281,"sourceCodeEnd":317,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/database/knowledge/knowledge.go#L281-L317","documentation":"ListUserDocuments lists knowledge documents scoped to a user. When no filter narrows the result set, it runs the SQLC query ListUserKnowledgeDocuments against the pgvector-backed tables; if that query fails (DB down, bad SQL, context canceled), the error is wrapped with the 'knowledge: list user docs' prefix and returned.","triggerScenarios":"Calling ListUserDocuments with no metadata filter while the PostgreSQL connection is unavailable, the query times out, or ctx is canceled mid-query.","commonSituations":"Database restarted or connection pool exhausted; pgvector extension missing after a fresh deploy so the SQLC query errors; request context canceled by a disconnected GraphQL client.","solutions":["Verify PostgreSQL is reachable and healthy (pg_isready, docker compose ps for the db service).","Check server logs for the underlying wrapped error; it names the true cause (connection refused, relation does not exist, context canceled).","Run backend/migrations (goose) to ensure knowledge/pgvector tables and the vector extension exist.","Retry the request; transient connection-pool exhaustion resolves after load drops."],"exampleFix":"// before\nrows, err := ks.db.ListUserKnowledgeDocuments(ctx, nsOf(userIDStr)) // fails when DB unreachable\n// after\nif err := ks.db.Ping(ctx); err != nil {\n    return nil, fmt.Errorf(\"knowledge: db unavailable: %w\", err)\n}\nrows, err := ks.db.ListUserKnowledgeDocuments(ctx, nsOf(userIDStr))","handlingStrategy":"try-catch","validationCode":"if err := dbConn.PingContext(ctx); err != nil {\n    return nil, fmt.Errorf(\"database unavailable: %w\", err)\n}\nif ctx.Err() != nil {\n    return nil, ctx.Err()\n}","typeGuard":"func isDBUnavailable(err error) bool {\n    var opErr *net.OpError\n    return errors.As(err, &opErr) || errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded)\n}","tryCatchPattern":"docs, err := store.ListUserDocuments(ctx, userID, filter, true)\nif err != nil {\n    if isDBUnavailable(err) {\n        return fmt.Errorf(\"knowledge temporarily unavailable: %w\", err)\n    }\n    return err\n}","preventionTips":["Run goose migrations at deploy time so knowledge tables always exist.","Monitor DB connection-pool saturation and set sane pool limits.","Always pass a request-scoped context with a reasonable timeout.","Alert on database connectivity so users see a health banner, not raw errors."],"tags":["database","postgresql","sqlc"],"backgroundTag":"database-query-failed","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}