{"record":{"id":"103bb714c1734526","repo":"vitessio/vitess","slug":"bad-encoding","errorCode":null,"errorMessage":"bad encoding","messagePattern":"bad encoding","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/mysql/binlog_event_make.go","lineNumber":380,"sourceCode":"\tpos := 6 + 2 + 1 + copy(data[9:], tm.Database)\n\tdata[pos] = 0\n\tpos++\n\tdata[pos] = byte(len(tm.Name))\n\tpos += 1 + copy(data[pos+1:], tm.Name)\n\tdata[pos] = 0\n\tpos++\n\n\tpos = writeLenEncInt(data, pos, uint64(len(tm.Types)))\n\tpos += copy(data[pos:], tm.Types)\n\n\tpos = writeLenEncInt(data, pos, uint64(metadataLength))\n\tfor c, typ := range tm.Types {\n\t\tpos = metadataWrite(data, pos, typ, tm.Metadata[c])\n\t}\n\n\tpos += copy(data[pos:], tm.CanBeNull.data)\n\tif pos != len(data) {\n\t\tpanic(\"bad encoding\")\n\t}\n\n\tev := s.Packetize(f, eTableMapEvent, 0, data)\n\treturn NewMariadbBinlogEvent(ev)\n}\n\n// NewRowsQueryEvent returns a ROWS_QUERY_LOG_EVENT containing the given SQL query\n// which is encoded as a NULL byte terminated string.\nfunc NewRowsQueryEvent(f BinlogFormat, s *FakeBinlogStream, query string) BinlogEvent {\n\tlength := 1 + // post-header (always 1 byte)\n\t\tlen(query) + // SQL query\n\t\t1 // NULL byte terminator\n\tdata := make([]byte, length)\n\tdata[0] = 1 // post-header length byte which is ignored\n\tcopy(data[1:], query)\n\t// data[length-1] is already 0 (NULL byte terminator)\n\n\tev := s.Packetize(f, eRowsQueryEvent, 0, data)","sourceCodeStart":362,"sourceCodeEnd":398,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/mysql/binlog_event_make.go#L362-L398","documentation":"NewTableMapEvent panics with \"bad encoding\" as a self-check after serializing the table-map event: the number of bytes written into the buffer does not match the pre-computed buffer length. This indicates an internal inconsistency in the metadata encoding (e.g. a column type whose metadata size was computed differently than written).","triggerScenarios":"Calling NewTableMapEvent with a TableMap whose Types include a type that metadataLength and metadataWrite size differently, or with inconsistent Metadata/CanBeNull data so pos != len(data) after serialization.","commonSituations":"Tests using synthetic column types (types the metadata functions don't recognize); hand-built TableMap structs with mismatched Types/Metadata arrays; changes to the type list without updating both size computation and writer.","solutions":["Use only supported MySQL column types in TableMap.Types.","Ensure Metadata entries correspond one-to-one with Types and use the expected widths.","If a new type is needed, update metadataLength, metadataWrite, and metadataRead consistently."],"exampleFix":"// before\ntm.Types = []byte{0xF9 /* unsupported synthetic */}\nev := mysql.NewTableMapEvent(f, s, id, tm) // panics: bad encoding\n// after\ntm.Types = []byte{binlog.TypeVarchar}\ntm.Metadata = []uint16{uint16(len(colDef))}\nev := mysql.NewTableMapEvent(f, s, id, tm)","handlingStrategy":"validation","validationCode":"for _, typ := range tm.Types {\n    switch typ {\n    case binlog.TypeVarchar, binlog.TypeBit, binlog.TypeVarString, /* ...supported... */ :\n    default:\n        return errors.Errorf(\"unsupported column type %d in TableMap\", typ)\n    }\n}","typeGuard":null,"tryCatchPattern":"func safeTableMapEvent(f mysql.BinlogFormat, s *mysql.FakeBinlogStream, id uint64, tm *mysql.TableMap) (ev mysql.BinlogEvent, err error) {\n    defer func() {\n        if r := recover(); r != nil {\n            err = fmt.Errorf(\"NewTableMapEvent: %v\", r)\n        }\n    }()\n    return mysql.NewTableMapEvent(f, s, id, tm), nil\n}","preventionTips":["Keep Types, Metadata, and CanBeNull arrays the same length and mutually consistent.","Only use binlog.Type* constants in TableMap.Types.","Update metadataLength and metadataWrite together when adding types."],"tags":["mysql","binlog","encoding","panics"],"backgroundTag":"encoding-length-mismatch","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}