{"record":{"id":"647c5c7ae9608485","repo":"vxcontrol/pentagi","slug":"failed-to-fetch-resources-w","errorCode":null,"errorMessage":"failed to fetch resources: %w","messagePattern":"failed to fetch resources: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/pkg/server/services/assistants.go","lineNumber":662,"sourceCode":"}\n\n// validateServiceResources fetches and validates user resource ownership for REST handlers.\n// It mirrors the logic in validateUserResources from the graph package but works with *gorm.DB.\n// privs must contain at least \"resources.view\" or \"resources.admin\"; otherwise permission is denied.\n// \"resources.admin\" bypasses the user_id ownership check.\nfunc validateServiceResources(db *gorm.DB, uid uint64, privs []string, ids []uint64) ([]database.UserResource, error) {\n\tif len(ids) == 0 {\n\t\treturn nil, nil\n\t}\n\n\tisAdmin := slices.Contains(privs, \"resources.admin\")\n\tif !isAdmin && !slices.Contains(privs, \"resources.view\") && len(ids) > 0 {\n\t\treturn nil, fmt.Errorf(\"permission 'resources.view' required to use resource IDs\")\n\t}\n\n\tvar recs []models.UserResource\n\tif err := db.Model(&models.UserResource{}).Where(\"id IN (?)\", ids).Find(&recs).Error; err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to fetch resources: %w\", err)\n\t}\n\n\tfound := make(map[uint64]models.UserResource, len(recs))\n\tfor _, r := range recs {\n\t\tfound[r.ID] = r\n\t}\n\n\tresult := make([]database.UserResource, 0, len(ids))\n\tfor _, id := range ids {\n\t\tr, ok := found[id]\n\t\tif !ok {\n\t\t\treturn nil, fmt.Errorf(\"resource %d not found\", id)\n\t\t}\n\t\tif !isAdmin && r.UserID != uid {\n\t\t\treturn nil, fmt.Errorf(\"resource %d not accessible\", id)\n\t\t}\n\t\tresult = append(result, database.UserResource{\n\t\t\tID:        int64(r.ID),","sourceCodeStart":644,"sourceCodeEnd":680,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/server/services/assistants.go#L644-L680","documentation":"Wraps the GORM error returned while loading models.UserResource rows with WHERE id IN (ids) during validateServiceResources. The permission checks have already passed; this is a database-level failure while fetching the referenced resource records, with the underlying driver error preserved via %w.","triggerScenarios":"CreateFlowAssistant, PatchAssistant, CreateFlow, or PatchFlow invoked with resource IDs while the database query fails: DB unreachable, connection pool exhausted, table missing (migration not applied), or context timeout/cancellation mid-query.","commonSituations":"PostgreSQL down or restarting; wrong DB credentials after redeploy; running the binary against a schema missing the user_resources table; large IN-list hitting statement timeouts.","solutions":["Check backend logs for the wrapped cause (connection refused / relation does not exist / timeout).","Verify PostgreSQL is reachable and credentials in config are correct.","Run pending goose migrations (migrations in backend/migrations/sql/) so user_resources exists.","Retry the request once the database is healthy; if IDs are user-supplied, cap the list size to avoid oversized queries.","Add request timeout/health-check monitoring for the DB dependency."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// pre-flight DB health check before issuing resource-heavy requests\nif err := db.Exec(\"SELECT 1\").Error; err != nil {\n    return fmt.Errorf(\"database unavailable: %w\", err)\n}\nif len(ids) == 0 {\n    return nil, nil\n}","typeGuard":"func dbHealthy(db *gorm.DB) bool {\n    sqlDB, err := db.DB()\n    if err != nil { return false }\n    return sqlDB.Ping() == nil\n}","tryCatchPattern":"recs, err := validateServiceResources(ctx, uid, privs, ids)\nif err != nil {\n    var dbErr *gorm.DB\n    if errors.As(err, &dbErr) || strings.Contains(err.Error(), \"failed to fetch resources\") {\n        // transient DB issue: back off and retry once\n        time.Sleep(500 * time.Millisecond)\n        recs, err = validateServiceResources(ctx, uid, privs, ids)\n    }\n    if err != nil { return err }\n}","preventionTips":["Monitor PostgreSQL availability and connection-pool saturation","Apply all goose migrations so user_resources exists","Set sane statement timeouts and cap batch ID-list sizes","Add retry with backoff for transient DB errors in the service layer"],"tags":["database","gorm","postgresql","resources"],"backgroundTag":"database-query-failed","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}