{"record":{"id":"b6c1aa963f32021b","repo":"vitessio/vitess","slug":"internal-error-unexpected-rows-without-fields","errorCode":null,"errorMessage":"internal error: unexpected rows without fields","messagePattern":"internal error: unexpected rows without fields","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vttablet/tabletserver/messager/message_manager.go","lineNumber":755,"sourceCode":"\t\t\tcase binlogdatapb.VEventType_COMMIT, binlogdatapb.VEventType_DDL, binlogdatapb.VEventType_OTHER:\n\t\t\t\t// Update curPos only when the GTID concludes, which is through one\n\t\t\t\t// of the above events.\n\t\t\t\tcurPos = newPos\n\t\t\t\tskipEvents, err = mustSkip()\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}, nil)\n\treturn err\n}\n\nfunc (mm *messageManager) processRowEvent(fields []*querypb.Field, rowEvent *binlogdatapb.RowEvent) error {\n\tif fields == nil {\n\t\t// Unreachable.\n\t\treturn errors.New(\"internal error: unexpected rows without fields\")\n\t}\n\n\tnow := time.Now().UnixNano()\n\tfor _, rc := range rowEvent.RowChanges {\n\t\tif rc.After == nil {\n\t\t\tcontinue\n\t\t}\n\t\trow := sqltypes.MakeRowTrusted(fields, rc.After)\n\t\tmr, err := BuildMessageRow(row)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif mr.TimeAcked != 0 || mr.TimeNext > now {\n\t\t\tcontinue\n\t\t}\n\t\tmm.Add(mr)\n\t}\n\treturn nil","sourceCodeStart":737,"sourceCodeEnd":773,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vttablet/tabletserver/messager/message_manager.go#L737-L773","documentation":"messager's processRowEvent requires the field metadata that accompanies row events; row changes cannot be interpreted without it. This error is marked \"Unreachable\" in code — it's an invariant check that fires only if a RowEvent arrives with nil fields, which should be impossible from the VStream protocol.","triggerScenarios":"processRowEvent is invoked with fields == nil — i.e. a binlogdatapb.RowEvent is delivered through the message stream without its associated field metadata, indicating a protocol bug.","commonSituations":"VReplication/VStream bugs where FieldEvents were dropped or reordered; custom vstream clients or middlemen stripping field events; corrupted stream relay logic.","solutions":["This indicates an internal bug — file an issue with vttablet logs and the binlog event sequence around the failure","Check for intermediate vstream consumers/proxies between source and messager that may drop FieldEvent messages","Restart the vreplication stream/messager to re-establish fields; if reproducible, capture the VStream events with a debug client"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := mm.processRowEvent(fields, rowEvent); err != nil {\n    if strings.Contains(err.Error(), \"unexpected rows without fields\") {\n        // protocol bug: capture diagnostics and restart the stream\n        log.Error(\"row event arrived without field metadata; restarting stream\", slog.Any(\"error\", err))\n        return restartStream(ctx)\n    }\n    return err\n}","preventionTips":["Don't insert custom VStream consumers that drop FieldEvent messages","Keep Vitess components on compatible versions (no mixed old/new vstreaming)","Report reproducible occurrences with full vttablet logs — this is an internal invariant violation"],"tags":["messager","binlog","internal-error","protocol"],"backgroundTag":"missing-metadata-field","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}