vitessio/vitess · error

ExecNoPrepare unexpected error: %+v

Error message

ExecNoPrepare unexpected error: %+v

What it means

ExecNoPrepare runs db.Exec without prepared statements, wrapped in a recover guard. If the supplied callback-free execution path panics — typically inside driver code or argument marshaling — the panic is converted into this error. Like QueryRowsMap's recover, it indicates a Go panic happened, not an ordinary SQL error.

Source

Thrown at go/vt/external/golib/sqlutils/sqlutils.go:249

	var rows *sql.Rows
	rows, err = db.Query(query, args...)
	if rows != nil {
		defer rows.Close()
	}
	if err != nil && err != sql.ErrNoRows {
		log.Error(fmt.Sprint(err))
		return err
	}
	err = ScanRowsToMaps(rows, on_row)
	return
}

// ExecNoPrepare executes given query using given args on given DB, without using prepared statements.
func ExecNoPrepare(db *sql.DB, query string, args ...any) (res sql.Result, err error) {
	defer func() {
		if derr := recover(); derr != nil {
			err = fmt.Errorf("ExecNoPrepare unexpected error: %+v", derr)
		}
	}()

	res, err = db.Exec(query, args...)
	if err != nil {
		log.Error(fmt.Sprint(err))
	}
	return res, err
}

// Convert variable length arguments into arguments array
func Args(args ...any) []any {
	return args
}

func NilIfZero(i int64) any {
	if i == 0 {
		return nil

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Inspect the recovered panic value in the message and fix the argument/handle bug at the call site
  2. Verify the *sql.DB passed in is non-nil and properly opened before calling ExecNoPrepare
  3. Ensure all query args are driver-supported scalar types (strings, ints, []byte, time.Time, sql.Null*)

Example fix

// before
sqlutils.ExecNoPrepare(db, q, args...)
// after
if db == nil {
    return fmt.Errorf("db handle is nil")
}
sqlutils.ExecNoPrepare(db, q, args...)
Defensive patterns

Strategy: validation

Validate before calling

if db == nil {
    return fmt.Errorf("ExecNoPrepare: nil *sql.DB")
}
for i, a := range args {
    switch a.(type) {
    case nil, string, int, int64, float64, bool, []byte, time.Time:
    default:
        return fmt.Errorf("ExecNoPrepare: unsupported arg type at %d: %T", i, a)
    }
}

Try / catch

if _, err := sqlutils.ExecNoPrepare(db, q, args...); err != nil {
    if strings.Contains(err.Error(), "unexpected error") {
        log.Errorf("panic converted to error: %v", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling sqlutils.ExecNoPrepare where db.Exec or argument conversion panics: nil *sql.DB pointer, driver panic on malformed args, or unsupported value types passed in args.

Common situations: Passing a nil db handle into a helper; passing unsupported types (e.g. channels, funcs) as query args; driver bugs with certain value types in no-prepare mode.

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/47d26931379013e6. Report an issue: GitHub.