{"record":{"id":"8973cc64874dd3ba","repo":"vitessio/vitess","slug":"stream-needs-a-position-or-a-table-to-copy","errorCode":null,"errorMessage":"stream needs a position or a table to copy","messagePattern":"stream needs a position or a table to copy","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vttablet/tabletserver/vstreamer/uvstreamer.go","lineNumber":440,"sourceCode":"// 2. TablePKs nil, startPos empty => full table copy of tables matching filter\n// 3. TablePKs not nil, startPos empty => table copy (for pks > lastPK)\n// 4. TablePKs not nil, startPos set => run catchup from startPos, then table copy  (for pks > lastPK)\n//\n// If table copy phase should run based on one of the previous states, then only copy the tables in\n// TablesToCopy list.\nfunc (uvs *uvstreamer) init() error {\n\tif uvs.startPos == \"\" /* full copy */ || len(uvs.inTablePKs) > 0 /* resume copy */ {\n\t\tif err := uvs.buildTablePlan(); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif uvs.startPos != \"\" {\n\t\tif err := uvs.setStreamStartPosition(); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif uvs.pos.IsZero() && (len(uvs.plans) == 0) {\n\t\treturn errors.New(\"stream needs a position or a table to copy\")\n\t}\n\treturn nil\n}\n\n// Stream streams binlog events.\nfunc (uvs *uvstreamer) Stream() error {\n\tlog.Info(\"Stream() called\")\n\tif err := uvs.init(); err != nil {\n\t\treturn err\n\t}\n\tif len(uvs.plans) > 0 {\n\t\tlog.Info(\"TablePKs is not nil: starting vs.copy()\")\n\t\tif err := uvs.copy(uvs.ctx); err != nil {\n\t\t\tlog.Info(fmt.Sprintf(\"uvstreamer.Stream() copy returned with err %s\", err))\n\t\t\tuvs.vse.errorCounts.Add(\"Copy\", 1)\n\t\t\treturn err\n\t\t}\n\t\tif err := uvs.allCopyComplete(); err != nil {","sourceCodeStart":422,"sourceCodeEnd":458,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vttablet/tabletserver/vstreamer/uvstreamer.go#L422-L458","documentation":"The uvstreamer cannot start because it has neither a valid starting GTID position nor any table copy plans. A vreplication stream must either resume from a position or copy at least one table; with both missing there is nothing to stream. This guard in init() prevents launching a stream that would produce no events.","triggerScenarios":"Calling uvstreamer.Stream() when uvs.pos is zero and uvs.plans is empty — e.g. a VReplication stream created without a stop/start position and with an empty or fully filtered table list, or a plan-building failure that silently left plans empty.","commonSituations":"Misconfigured MoveTables/Reshard workflows where the source table list resolved to nothing; a workflow whose copy phase finished and whose starting position was lost or never recorded; manually inserting vreplication rows with an empty pos.","solutions":["Set a valid starting position (pos/startPos GTID) on the stream so setStreamStartPosition can seed uvs.pos","Ensure the workflow includes at least one table to copy so plans are built","Inspect the _vt.vreplication row for the stream and fix its message/pos, then restart the workflow with Workflow <ks>.<wf> start"],"exampleFix":"// before: stream row with empty pos and no tables\n// after: restart with explicit position or correct table filter\nworkflow := \"ks.mt1\"\nvtctldclient Workflow --keyspace ks moveTables --workflow mt1 --tables a,b start","handlingStrategy":"validation","validationCode":"-- before creating/restarting a stream\nSELECT workflow, pos, message FROM _vt.vreplication WHERE workflow='<wf>';\n-- pos must be non-empty OR the workflow must list tables to copy","typeGuard":null,"tryCatchPattern":"if err := streamer.Stream(); err != nil {\n\tif strings.Contains(err.Error(), \"needs a position or a table\") {\n\t\t// fix workflow config: set pos or table list, then restart\n\t}\n\treturn err\n}","preventionTips":["Always start workflows via vtctldclient Workflow start rather than raw inserts","Confirm the workflow recorded a valid pos after copy phase completes","Validate table filters resolve to non-empty lists before creating the workflow"],"tags":["vreplication","vstreamer","configuration"],"backgroundTag":"vreplication-no-stream-source","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}