go-gorm/gorm · error

unsupported select args %v %v

Error message

unsupported select args %v %v

What it means

db.Select accepts either []string (plus optional string/[]string variadic args) or a string template with '?' placeholders. If query is []string but an arg is neither string nor []string (e.g. int, struct), GORM adds fmt.Errorf("unsupported select args %v %v", query, args) and stops building the SELECT clause. It is a client-side argument-type validation error, not SQL.

Source

Thrown at chainable_api.go:126

//	// Select name and age of user using multiple arguments
//	db.Select("name", "age").Find(&users)
//	// Select name and age of user using an array
//	db.Select([]string{"name", "age"}).Find(&users)
func (db *DB) Select(query interface{}, args ...interface{}) (tx *DB) {
	tx = db.getInstance()

	switch v := query.(type) {
	case []string:
		tx.Statement.Selects = v

		for _, arg := range args {
			switch arg := arg.(type) {
			case string:
				tx.Statement.Selects = append(tx.Statement.Selects, arg)
			case []string:
				tx.Statement.Selects = append(tx.Statement.Selects, arg...)
			default:
				tx.AddError(fmt.Errorf("unsupported select args %v %v", query, args))
				return
			}
		}

		if clause, ok := tx.Statement.Clauses["SELECT"]; ok {
			clause.Expression = nil
			tx.Statement.Clauses["SELECT"] = clause
		}
	case string:
		if strings.Count(v, "?") >= len(args) && len(args) > 0 {
			tx.Statement.AddClause(clause.Select{
				Distinct:   db.Statement.Distinct,
				Expression: clause.Expr{SQL: v, Vars: args},
			})
		} else if strings.Count(v, "@") > 0 && len(args) > 0 {
			tx.Statement.AddClause(clause.Select{
				Distinct:   db.Statement.Distinct,
				Expression: clause.NamedExpr{SQL: v, Vars: args},

View on GitHub (pinned to 1d6ce99528)

Solutions

  1. Keep list-form Select args strings only: convert values with fmt.Sprint(v).
  2. For expression-based selection use the template form Select("price * ? AS total", qty).
  3. Validate/normalize column lists at config load time (all entries must be strings).
  4. Check tx.Error right after Select in dynamic query builders to fail fast.

Example fix

// before
db.Select([]string{"name"}, 42).Find(&users)

// after
db.Select([]string{"name", fmt.Sprint(42)}).Find(&users)
// or template form:
db.Select("?", 42).Find(&users)
Defensive patterns

Strategy: validation

Validate before calling

func validSelectArgs(args ...interface{}) error {
    for _, a := range args {
        switch a.(type) {
        case string, []string:
        default:
            return fmt.Errorf("Select arg %v must be string or []string", a)
        }
    }
    return nil
}
// normalize before calling Select:
cols := toStrings(configColumns) // all entries strings
db.Select(cols)

Type guard

func isSelectArgOK(v interface{}) bool {
    switch v.(type) {
    case string, []string: return true
    default: return false
    }
}

Try / catch

tx := db.Select(cols, args...)
if tx.Error != nil && strings.Contains(tx.Error.Error(), "unsupported select args") {
    // convert non-string args via fmt.Sprint and rebuild the Select
}

Prevention

When it happens

Trigger: db.Select([]string{"id", "name"}, 5) or Select([]string{"name"}, someStruct); also dynamically building args and letting a non-string type slip in (interface{} slices from config or JSON).

Common situations: Passing constants for a template Select into the []string form: Select([]string{"name"}, clause.Eq{...}); config-driven column lists where one entry is a number; refactors moving args from Select("?", x) to the list form without converting x to string.

Related errors


AI-assisted analysis of go-gorm/gorm@1d6ce99528 (2026-08-15). Data as JSON: /api/errors/d6e312ea942b2feb. Report an issue: GitHub.