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
- Keep list-form Select args strings only: convert values with fmt.Sprint(v).
- For expression-based selection use the template form Select("price * ? AS total", qty).
- Validate/normalize column lists at config load time (all entries must be strings).
- 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
- Use the list form Select([]string{...}) only with strings; use the template form Select("?", v) for values.
- Normalize config-driven column lists to []string at load time.
- Check tx.Error immediately after Select in dynamic builders - it fails before any SQL runs.
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.