vitessio/vitess · error

bad sql row

Error message

bad sql row

What it means

fakevtsql.ErrBadRow is returned by the fake driver's rows.Next when a configured row has a different number of values than the row's column count. It validates the fixture itself: test data must be rectangular relative to declared columns. It indicates a mistake in test setup, not in production code.

Source

Thrown at go/vt/vtadmin/vtsql/fakevtsql/rows.go:29

distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package fakevtsql

import (
	"database/sql/driver"
	"errors"
	"fmt"
	"io"
)

var (
	// ErrBadRow is returned from Next() when a row has an incorrect number of
	// fields.
	ErrBadRow = errors.New("bad sql row")
	// ErrRowsClosed is returned when attempting to operate on an already-closed
	// Rows.
	ErrRowsClosed = errors.New("err rows closed")
)

type rows struct {
	cols []string
	vals [][]any
	pos  int

	closed bool
}

var _ driver.Rows = (*rows)(nil)

func (r *rows) Close() error {
	r.closed = true
	return nil

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Fix the fixture so every row has exactly len(cols) values
  2. Verify each row's length in the test helper before handing it to the fake
  3. Regenerate the fixture after column changes

Example fix

// before
cols := []string{"id", "name"}
vals := [][]any{{1, "a"}, {2}} // short row
// after
vals := [][]any{{1, "a"}, {2, "b"}}
Defensive patterns

Strategy: validation

Validate before calling

for i, row := range vals {
    if len(row) != len(cols) {
        t.Fatalf("fixture row %d has %d values, want %d", i, len(row), len(cols))
    }
}

Type guard

func isBadRow(err error) bool { return errors.Is(err, fakevtsql.ErrBadRow) }

Try / catch

for rows.Next() {
    if err := rows.Err(); errors.Is(err, fakevtsql.ErrBadRow) {
        t.Fatalf("bad fixture row: %v", err)
    }
}

Prevention

When it happens

Trigger: Registering a rows fixture where some row slice has fewer or more entries than the column list passed to the fake; programmatically building rows where one branch appends fewer values.

Common situations: Hand-written test rows with a missing value after adding a column; building rows from variable-length data in test helpers.

Related errors


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