{"record":{"id":"7afaaa4c30dec7c0","repo":"vitessio/vitess","slug":"cannot-determine-table-columns-for-s-event-has","errorCode":null,"errorMessage":"cannot determine table columns for %s: event has %v, schema has %v","messagePattern":"cannot determine table columns for (.+?): event has (.+?), schema has (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vttablet/tabletserver/vstreamer/vstreamer.go","lineNumber":938,"sourceCode":"\t\tfound := slices.Contains(vs.options.InternalTables, tableName)\n\t\tif !found {\n\t\t\treturn nil, nil\n\t\t}\n\t}\n\n\tconn, err := vs.cp.Connect(vs.ctx)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer conn.Close()\n\tqr, err := conn.ExecuteFetch(sqlparser.BuildParsedQuery(\"select * from %s.%s where 1 != 1\",\n\t\tsidecar.GetIdentifier(), tableName).Query, 1, true)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tfields := qr.Fields\n\tif len(fields) < len(tm.Types) {\n\t\treturn nil, fmt.Errorf(\"cannot determine table columns for %s: event has %v, schema has %v\", tm.Name, tm.Types, fields)\n\t}\n\ttable := &Table{\n\t\tName:   tableName,\n\t\tFields: fields[:len(tm.Types)],\n\t}\n\n\t// Build a normal table plan, which means, return all rows\n\t// and columns as is. Special handling may be done when we actually\n\t// receive the row event, example: we'll build a JOURNAL or VERSION event instead.\n\tplan, err := buildREPlan(vs.se.Environment(), table, nil, \"\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tplan.IsInternal = true\n\tvs.plans[id] = &streamerPlan{\n\t\tPlan:     plan,\n\t\tTableMap: tm,\n\t}","sourceCodeStart":920,"sourceCodeEnd":956,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go#L920-L956","documentation":"When building the row-decode plan for a sidecar (internal _vt style) table, vstreamer compares the column types embedded in the ROWS event's TableMap with the fields fetched from the live schema. If the schema query returns fewer fields than the event declares, the columns cannot be reconciled and the plan build fails.","triggerScenarios":"buildSidecarTablePlan executes the schema query for the sidecar table, gets qr.Fields shorter than tm.Types (the column count declared by the binlog TableMap event), and errors out.","commonSituations":"Schema drift between the binlog stream (older or newer table definition) and the current sidecar table schema; an online schema change of a _vt table while vreplication is streaming; stale schema cache in vttablet.","solutions":["Reload the table schema in vttablet so the schema engine matches the current table definition","Ensure the sidecar table schema matches the version writing the binlog events (complete any pending schema migrations)","Restart the vstream/vreplication workflow from a position after the schema change","Verify no concurrent DDL on the sidecar table during streaming"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Compare live schema vs event expectation:\n// SELECT COUNT(*) FROM information_schema.columns WHERE table_schema='_vt' AND table_name='<sidecar_table>';","typeGuard":null,"tryCatchPattern":"if strings.Contains(err.Error(), \"cannot determine table columns\") {\n    // trigger vttablet schema reload, then retry the vstream\n}","preventionTips":["Avoid concurrent DDL on sidecar tables during vreplication","Complete schema migrations before/after streams, not mid-stream","Reload vttablet schema after any _vt table change"],"tags":["schema","sidecar-table","columns","vstreamer"],"backgroundTag":"schema-column-mismatch","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}