{"record":{"id":"420056bb4ff4ba53","repo":"vitessio/vitess","slug":"invalid-filepos-gtid-v-expecting-pos-to-be-an","errorCode":null,"errorMessage":"invalid FilePos GTID (%v): expecting pos to be an integer","messagePattern":"invalid FilePos GTID \\((.+?)\\): expecting pos to be an integer","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/mysql/replication/filepos_gtid.go","lineNumber":38,"sourceCode":"\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// FilePosFlavorID is the string identifier for the filePos flavor.\nconst FilePosFlavorID = \"FilePos\"\n\n// parsefilePosGTID is registered as a GTID parser.\nfunc parseFilePosGTID(s string) (GTID, error) {\n\t// Split into parts.\n\tparts := strings.Split(s, \":\")\n\tif len(parts) != 2 {\n\t\treturn nil, fmt.Errorf(\"invalid FilePos GTID (%v): expecting file:pos\", s)\n\t}\n\n\tpos, err := strconv.ParseUint(parts[1], 0, 64)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid FilePos GTID (%v): expecting pos to be an integer\", s)\n\t}\n\n\treturn FilePosGTID{\n\t\tFile: parts[0],\n\t\tPos:  pos,\n\t}, nil\n}\n\n// ParseFilePosGTIDSet is registered as a GTIDSet parser.\nfunc ParseFilePosGTIDSet(s string) (GTIDSet, error) {\n\tgtid, err := parseFilePosGTID(s)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn gtid.(FilePosGTID), err\n}\n\n// FilePosGTID implements GTID.","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/mysql/replication/filepos_gtid.go#L20-L56","documentation":"After splitting a FilePos GTID on ':', the position part must parse as an unsigned 64-bit integer via strconv.ParseUint (base 0). If it does not, the string is rejected with this error even though the overall file:pos shape was correct.","triggerScenarios":"Calling ParseFilePosGTIDSet with values like `mysql-bin.000001:abc`, `mysql-bin.000001:-5`, `mysql-bin.000001:99999999999999999999999` (overflow beyond uint64), or a sequence list like `mysql-bin.000001:1-5`.","commonSituations":"Copy/paste of a binlog event range (file:1-5) into a position field expecting a single position; typos in manual replication setup; confusing MySQL GTID sequence notation with file/pos notation.","solutions":["Replace the position with a single plain integer, e.g. mysql-bin.000001:4521","Remove ranges (1-5) or non-numeric suffixes — file:pos accepts one position only","Verify the position fits in uint64 (no values above 18446744073709551615)"],"exampleFix":"// before\ngtid, err := mysql.ParseFilePosGTIDSet(\"mysql-bin.000001:1-5\")\n// after\ngtid, err := mysql.ParseFilePosGTIDSet(\"mysql-bin.000001:4521\")","handlingStrategy":"validation","validationCode":"func posIsSingleUint64(s string) bool {\n\tparts := strings.Split(s, \":\")\n\tif len(parts) != 2 {\n\t\treturn false\n\t}\n\tpos, err := strconv.ParseUint(parts[1], 0, 64)\n\treturn err == nil && pos >= 0 && !strings.Contains(parts[1], \"-\")\n}","typeGuard":null,"tryCatchPattern":"gtid, err := mysql.ParseFilePosGTIDSet(input)\nif err != nil {\n\tif strings.Contains(err.Error(), \"pos to be an integer\") {\n\t\t// strip ranges/typos or reject: a single numeric position is required\n\t}\n\treturn err\n}","preventionTips":["Never pass binlog ranges (file:1-5) as a position — pick a single position","Validate the position with strconv.ParseUint before parsing","Double-check manual replication setup values for typos and overflow"],"tags":["replication","gtid","parsing"],"backgroundTag":"invalid-gtid-format","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}