vxcontrol/pentagi · error

failed to fetch resources: %w

Error message

failed to fetch resources: %w

What it means

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.

Source

Thrown at backend/pkg/server/services/assistants.go:662

}

// validateServiceResources fetches and validates user resource ownership for REST handlers.
// It mirrors the logic in validateUserResources from the graph package but works with *gorm.DB.
// privs must contain at least "resources.view" or "resources.admin"; otherwise permission is denied.
// "resources.admin" bypasses the user_id ownership check.
func validateServiceResources(db *gorm.DB, uid uint64, privs []string, ids []uint64) ([]database.UserResource, error) {
	if len(ids) == 0 {
		return nil, nil
	}

	isAdmin := slices.Contains(privs, "resources.admin")
	if !isAdmin && !slices.Contains(privs, "resources.view") && len(ids) > 0 {
		return nil, fmt.Errorf("permission 'resources.view' required to use resource IDs")
	}

	var recs []models.UserResource
	if err := db.Model(&models.UserResource{}).Where("id IN (?)", ids).Find(&recs).Error; err != nil {
		return nil, fmt.Errorf("failed to fetch resources: %w", err)
	}

	found := make(map[uint64]models.UserResource, len(recs))
	for _, r := range recs {
		found[r.ID] = r
	}

	result := make([]database.UserResource, 0, len(ids))
	for _, id := range ids {
		r, ok := found[id]
		if !ok {
			return nil, fmt.Errorf("resource %d not found", id)
		}
		if !isAdmin && r.UserID != uid {
			return nil, fmt.Errorf("resource %d not accessible", id)
		}
		result = append(result, database.UserResource{
			ID:        int64(r.ID),

View on GitHub (pinned to ea665308ba)

Solutions

  1. Check backend logs for the wrapped cause (connection refused / relation does not exist / timeout).
  2. Verify PostgreSQL is reachable and credentials in config are correct.
  3. Run pending goose migrations (migrations in backend/migrations/sql/) so user_resources exists.
  4. Retry the request once the database is healthy; if IDs are user-supplied, cap the list size to avoid oversized queries.
  5. Add request timeout/health-check monitoring for the DB dependency.
Defensive patterns

Strategy: retry

Validate before calling

// pre-flight DB health check before issuing resource-heavy requests
if err := db.Exec("SELECT 1").Error; err != nil {
    return fmt.Errorf("database unavailable: %w", err)
}
if len(ids) == 0 {
    return nil, nil
}

Type guard

func dbHealthy(db *gorm.DB) bool {
    sqlDB, err := db.DB()
    if err != nil { return false }
    return sqlDB.Ping() == nil
}

Try / catch

recs, err := validateServiceResources(ctx, uid, privs, ids)
if err != nil {
    var dbErr *gorm.DB
    if errors.As(err, &dbErr) || strings.Contains(err.Error(), "failed to fetch resources") {
        // transient DB issue: back off and retry once
        time.Sleep(500 * time.Millisecond)
        recs, err = validateServiceResources(ctx, uid, privs, ids)
    }
    if err != nil { return err }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

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/647c5c7ae9608485. Report an issue: GitHub.