{"record":{"id":"51433527f1742661","repo":"vitessio/vitess","slug":"expecting-field-event-first-got-v","errorCode":null,"errorMessage":"expecting field event first, got: %v","messagePattern":"expecting field event first, got: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vttablet/tabletmanager/vreplication/vcopier.go","lineNumber":494,"sourceCode":"\t\t\t}\n\t\t\tif rows.Throttled {\n\t\t\t\t_ = vc.vr.updateTimeThrottled(throttlerapp.RowStreamerName, rows.ThrottledReason)\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tif rows.Heartbeat {\n\t\t\t\t_ = vc.vr.updateHeartbeatTime(time.Now().Unix())\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\t// verify throttler is happy, otherwise keep looping\n\t\t\tif checkResult, ok := vc.vr.vre.throttlerClient.ThrottleCheckOKOrWaitAppName(ctx, throttlerapp.Name(vc.throttlerAppName)); ok {\n\t\t\t\tbreak // out of 'for' loop\n\t\t\t} else { // we're throttled\n\t\t\t\t_ = vc.vr.updateTimeThrottled(throttlerapp.VCopierName, checkResult.Summary())\n\t\t\t}\n\t\t}\n\t\tif !copyWorkQueue.isOpen {\n\t\t\tif len(rows.Fields) == 0 {\n\t\t\t\treturn fmt.Errorf(\"expecting field event first, got: %v\", rows)\n\t\t\t}\n\t\t\tif err := vc.fastForward(ctx, copyState, rows.Gtid); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tfieldEvent := &binlogdatapb.FieldEvent{\n\t\t\t\tTableName: initialPlan.SendRule.Match,\n\t\t\t}\n\t\t\tfor _, f := range rows.Fields {\n\t\t\t\tfieldEvent.Fields = append(fieldEvent.Fields, f.CloneVT())\n\t\t\t}\n\t\t\ttablePlan, err := plan.buildExecutionPlan(fieldEvent)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tfor _, f := range rows.Pkfields {\n\t\t\t\tpkfields = append(pkfields, f.CloneVT())\n\t\t\t}\n\t\t\tbuf := sqlparser.NewTrackedBuffer(nil)","sourceCodeStart":476,"sourceCodeEnd":512,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vttablet/tabletmanager/vreplication/vcopier.go#L476-L512","documentation":"When the copy work queue is not yet open for the current table, vcopier expects the stream to deliver the field event (FieldEvent) before any row events. If a rows event arrives with empty Fields metadata, the copier cannot interpret the row data and returns this error.","triggerScenarios":"copyNext receives a RowsEvent for a table whose copy queue is not open and rows.Fields is empty — i.e. the field schema was never sent/recorded for that table before rows arrived.","commonSituations":"Binlog stream ordering issues after controller restart; VReplication stream resuming mid-table where the cached field event was lost; source sending rows for a table whose schema info is not yet available.","solutions":["Restart the VReplication workflow/stream so field events are re-sent from the start of the copy phase","Check vttablet logs for earlier errors fetching field info for the table","Verify the table still exists and its schema is readable on the source","Retry the copy phase; if persistent, file with the binlog stream position details"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := vc.copyNext(ctx); err != nil {\n  if strings.Contains(err.Error(), \"expecting field event first\") {\n    // restart/resume the stream so the field event is re-sent\n  }\n  return err\n}","preventionTips":["Avoid restarting vttablet mid-copy; if needed, restart the whole copy phase","Monitor for earlier 'field info' fetch errors in logs","Keep the source schema stable during the copy phase"],"tags":["vreplication","vcopier","binlog","field-event"],"backgroundTag":"missing-field-event-before-rows","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}