{"record":{"id":"99f5b74ab6164c02","repo":"vitessio/vitess","slug":"bad-sql-row","errorCode":null,"errorMessage":"bad sql row","messagePattern":"bad sql row","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtadmin/vtsql/fakevtsql/rows.go","lineNumber":29,"sourceCode":"distributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage fakevtsql\n\nimport (\n\t\"database/sql/driver\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n)\n\nvar (\n\t// ErrBadRow is returned from Next() when a row has an incorrect number of\n\t// fields.\n\tErrBadRow = errors.New(\"bad sql row\")\n\t// ErrRowsClosed is returned when attempting to operate on an already-closed\n\t// Rows.\n\tErrRowsClosed = errors.New(\"err rows closed\")\n)\n\ntype rows struct {\n\tcols []string\n\tvals [][]any\n\tpos  int\n\n\tclosed bool\n}\n\nvar _ driver.Rows = (*rows)(nil)\n\nfunc (r *rows) Close() error {\n\tr.closed = true\n\treturn nil","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtadmin/vtsql/fakevtsql/rows.go#L11-L47","documentation":"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.","triggerScenarios":"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.","commonSituations":"Hand-written test rows with a missing value after adding a column; building rows from variable-length data in test helpers.","solutions":["Fix the fixture so every row has exactly len(cols) values","Verify each row's length in the test helper before handing it to the fake","Regenerate the fixture after column changes"],"exampleFix":"// before\ncols := []string{\"id\", \"name\"}\nvals := [][]any{{1, \"a\"}, {2}} // short row\n// after\nvals := [][]any{{1, \"a\"}, {2, \"b\"}}","handlingStrategy":"validation","validationCode":"for i, row := range vals {\n    if len(row) != len(cols) {\n        t.Fatalf(\"fixture row %d has %d values, want %d\", i, len(row), len(cols))\n    }\n}","typeGuard":"func isBadRow(err error) bool { return errors.Is(err, fakevtsql.ErrBadRow) }","tryCatchPattern":"for rows.Next() {\n    if err := rows.Err(); errors.Is(err, fakevtsql.ErrBadRow) {\n        t.Fatalf(\"bad fixture row: %v\", err)\n    }\n}","preventionTips":["Validate fixture shape before registering rows with the fake","Rebuild fixtures when columns change","Use struct-to-row helpers so column counts stay in sync"],"tags":["vtadmin","test-double","database"],"backgroundTag":"bad-sql-row","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}