{"record":{"id":"5a532aa46cbc8f6a","repo":"vitessio/vitess","slug":"failed-to-parse-stop-pos-column-v","errorCode":null,"errorMessage":"failed to parse stop_pos column: %v","messagePattern":"failed to parse stop_pos column: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"go/vt/binlog/binlogplayer/binlog_player.go","lineNumber":599,"sourceCode":"\t\treturn VRSettings{}, fmt.Errorf(\"checkpoint information not available in db for %v\", uid)\n\t}\n\tvrRow := qr.Named().Row()\n\n\tmaxTPS, err := vrRow.ToInt64(\"max_tps\")\n\tif err != nil {\n\t\treturn VRSettings{}, fmt.Errorf(\"failed to parse max_tps column: %v\", err)\n\t}\n\tmaxReplicationLag, err := vrRow.ToInt64(\"max_replication_lag\")\n\tif err != nil {\n\t\treturn VRSettings{}, fmt.Errorf(\"failed to parse max_replication_lag column: %v\", err)\n\t}\n\tstartPos, err := DecodePosition(vrRow.AsString(\"pos\", \"\"))\n\tif err != nil {\n\t\treturn VRSettings{}, fmt.Errorf(\"failed to parse pos column: %v\", err)\n\t}\n\tstopPos, err := replication.DecodePosition(vrRow.AsString(\"stop_pos\", \"\"))\n\tif err != nil {\n\t\treturn VRSettings{}, fmt.Errorf(\"failed to parse stop_pos column: %v\", err)\n\t}\n\tworkflowType, err := vrRow.ToInt32(\"workflow_type\")\n\tif err != nil {\n\t\treturn VRSettings{}, fmt.Errorf(\"failed to parse workflow_type column: %v\", err)\n\t}\n\tworkflowSubType, err := vrRow.ToInt32(\"workflow_sub_type\")\n\tif err != nil {\n\t\treturn VRSettings{}, fmt.Errorf(\"failed to parse workflow_sub_type column: %v\", err)\n\t}\n\tdeferSecondaryKeys, err := vrRow.ToBool(\"defer_secondary_keys\")\n\tif err != nil {\n\t\treturn VRSettings{}, fmt.Errorf(\"failed to parse defer_secondary_keys column: %v\", err)\n\t}\n\toptions := vrRow.AsString(\"options\", \"{}\")\n\tvar workflowOptions vtctldata.WorkflowOptions\n\tif err := json.Unmarshal([]byte(options), &workflowOptions); err != nil {\n\t\treturn VRSettings{}, fmt.Errorf(\"failed to parse options column: %v\", err)\n\t}","sourceCodeStart":581,"sourceCodeEnd":617,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/binlog/binlogplayer/binlog_player.go#L581-L617","documentation":"The stop_pos column stores the position at which the vreplication stream should stop (empty means run indefinitely). replication.DecodePosition failed on its value, meaning the stored stop position is not a decodable GTID set.","triggerScenarios":"DecodePosition on stop_pos fails: manually entered stop position in the wrong format, flavor mismatch (MariaDB vs MySQL GTID), truncated value, or a stray non-empty invalid string left after workflow edits.","commonSituations":"Users setting a stop point via direct SQL instead of the workflow API; cross-flavor restore; copy-paste of a position with a typo.","solutions":["Inspect: `select uid, stop_pos from _vt.vreplication where uid=<id>`.","Fix or clear it: `update _vt.vreplication set stop_pos='' where uid=<id>` to run without a stop point, or set a valid encoded GTID set.","If a stop point is required, capture it properly from the source (`SELECT @@global.gtid_executed`) and encode with the same flavor.","Prefer workflow-level commands (e.g. MoveTables complete) over hand-editing stop_pos."],"exampleFix":"// before: malformed stop point\nupdate _vt.vreplication set stop_pos='1-5' where uid=1;\n// after: valid GTID set or empty to disable\nupdate _vt.vreplication set stop_pos='' where uid=1;","handlingStrategy":"validation","validationCode":"qr, _ := dbClient.ExecuteFetch(fmt.Sprintf(\"SELECT stop_pos FROM _vt.vreplication WHERE uid=%d\", uid), 1)\nif len(qr.Rows) == 1 {\n\tsp := qr.Named().Row().AsString(\"stop_pos\", \"\")\n\tif sp != \"\" {\n\t\tif _, err := replication.DecodePosition(sp); err != nil {\n\t\t\treturn fmt.Errorf(\"stop_pos %q invalid; clear it or set a valid GTID set\", sp)\n\t\t}\n\t}\n}","typeGuard":"func isValidStopPos(sp string) bool {\n\tif sp == \"\" { return true } // empty means run indefinitely\n\t_, err := replication.DecodePosition(sp)\n\treturn err == nil\n}","tryCatchPattern":"settings, err := binlogplayer.ReadVRSettings(dbClient, uid)\nif err != nil && strings.Contains(err.Error(), \"failed to parse stop_pos\") {\n\t_, _ = dbClient.ExecuteFetch(fmt.Sprintf(\"UPDATE _vt.vreplication SET stop_pos='' WHERE uid=%d\", uid), 0)\n\tsettings, err = binlogplayer.ReadVRSettings(dbClient, uid)\n}","preventionTips":["Set stop points via workflow tooling, not raw SQL.","Empty stop_pos is valid and means 'never stop' — clear rather than guess.","Capture positions with the same MySQL flavor that will decode them.","Validate with replication.DecodePosition before writing."],"tags":["vreplication","gtid","parsing","data-corruption"],"backgroundTag":"invalid-gtid-position","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}