beego/beego · error

<Condition.And> args cannot empty

Error message

<Condition.And> args cannot empty

What it means

Beego ORM panics from Condition.And when the expression string is empty or no bind arguments are passed. Each AND clause is compiled to SQL with '?' placeholders mapped 1:1 to args, so an expression without at least one value would generate invalid or unbindable SQL. This is a programmer-input check on the condition builder API.

Source

Thrown at client/orm/orm_conds.go:64

// NewCondition return new condition struct
func NewCondition() *Condition {
	c := &Condition{}
	return c
}

// Raw add raw sql to condition
func (c Condition) Raw(expr string, sql string) *Condition {
	if len(sql) == 0 {
		panic(fmt.Errorf("<Condition.Raw> sql cannot empty"))
	}
	c.params = append(c.params, condValue{exprs: strings.Split(expr, ExprSep), sql: sql, isRaw: true})
	return &c
}

// And add expression to condition
func (c Condition) And(expr string, args ...interface{}) *Condition {
	if expr == "" || len(args) == 0 {
		panic(fmt.Errorf("<Condition.And> args cannot empty"))
	}
	c.params = append(c.params, condValue{exprs: strings.Split(expr, ExprSep), args: args})
	return &c
}

// AndNot add NOT expression to condition
func (c Condition) AndNot(expr string, args ...interface{}) *Condition {
	if expr == "" || len(args) == 0 {
		panic(fmt.Errorf("<Condition.AndNot> args cannot empty"))
	}
	c.params = append(c.params, condValue{exprs: strings.Split(expr, ExprSep), args: args, isNot: true})
	return &c
}

// AndCond combine a condition to current condition
func (c *Condition) AndCond(cond *Condition) *Condition {
	if c == cond {
		panic(fmt.Errorf("<Condition.AndCond> cannot use self as sub cond"))

View on GitHub (pinned to 939cfde380)

Solutions

  1. Use a placeholder and pass the value: cond.And("name = ?", "beego")
  2. When a filter is optional and has no value, skip the And call entirely instead of calling it with empty args
  3. For raw SQL fragments with no bind parameters use cond.Raw(expr, sql)
  4. Compose multiple predicates with separate And calls or NewCondition() sub-conditions

Example fix

// before
cond.And("status")
cond.And(fmt.Sprintf("id = %d", id))

// after
cond.And("status = ?", "active")
cond.And("id = ?", id)
Defensive patterns

Strategy: validation

Validate before calling

func andIf(c *orm.Condition, expr string, args ...interface{}) *orm.Condition {
    if expr == "" || len(args) == 0 {
        return c // nothing to add; skip instead of panicking
    }
    return c.And(expr, args...)
}

Try / catch

defer func() {
    if r := recover(); r != nil {
        err = fmt.Errorf("condition build failed: %v", r)
    }
}()

Prevention

When it happens

Trigger: cond.And("status") with no variadic args; cond.And(""); inlining the literal into the SQL string (cond.And("id = 5")) which leaves len(args)==0 even though the predicate is complete.

Common situations: Dynamically assembled filters where an args slice is empty because the filter list is empty; refactoring placeholder queries into string-interpolated SQL; copying Raw()-style fragments into And().

Related errors


AI-assisted analysis of beego/beego@939cfde380 (2026-08-15). Data as JSON: /api/errors/d10d2012dba4176a. Report an issue: GitHub.