{"record":{"id":"94aab9d632c26cdc","repo":"vitessio/vitess","slug":"panic-err","errorCode":null,"errorMessage":"panic(err)","messagePattern":"panic\\(err\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/mysql/replication/gtid.go","lineNumber":75,"sourceCode":"}\n\n// gtidParsers maps flavor names to parser functions.\nvar gtidParsers = make(map[string]func(string) (GTID, error))\n\n// ParseGTID calls the GTID parser for the specified flavor.\nfunc ParseGTID(flavor, value string) (GTID, error) {\n\tparser := gtidParsers[flavor]\n\tif parser == nil {\n\t\treturn nil, vterrors.Errorf(vtrpc.Code_INTERNAL, \"parse error: unknown GTID flavor %#v\", flavor)\n\t}\n\treturn parser(value)\n}\n\n// MustParseGTID calls ParseGTID and panics on error.\nfunc MustParseGTID(flavor, value string) GTID {\n\tgtid, err := ParseGTID(flavor, value)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn gtid\n}\n\n// EncodeGTID returns a string that contains both the flavor and value of the\n// GTID, so that the correct parser can be selected when that string is passed\n// to DecodeGTID.\nfunc EncodeGTID(gtid GTID) string {\n\tif gtid == nil {\n\t\treturn \"\"\n\t}\n\n\treturn fmt.Sprintf(\"%s/%s\", gtid.Flavor(), gtid.String())\n}\n\n// DecodeGTID converts a string in the format returned by EncodeGTID back into\n// a GTID interface value with the correct underlying flavor.\nfunc DecodeGTID(s string) (GTID, error) {","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/mysql/replication/gtid.go#L57-L93","documentation":"MustParseGTID is the panicking variant of ParseGTID: it parses a GTID of a given flavor (e.g. \"MySQL56\", \"MariaDB\") and panics with the parse error instead of returning it. It exists for call sites where the input is known-valid (tests, constants); feeding it user-controlled or unparsed input turns a normal parse failure into a panic/crash.","triggerScenarios":"Calling MustParseGTID(flavor, value) where ParseGTID fails: unknown flavor, malformed value like \"ddd6e3a4-...:notanumber\", or empty value.","commonSituations":"Passing server UUIDs/GTID strings read from config files, command-line flags, or topology data that contain typos or were produced by a different MySQL flavor.","solutions":["Use ParseGTID and handle the error instead of the Must* variant for any runtime/user-supplied input","Validate the GTID string format (flavor and value) before calling MustParseGTID","Check that the flavor string matches the source server (MySQL56 vs MariaDB vs RocksmarTDB) — mixing flavors is a common cause"],"exampleFix":"// before\ngtid := replication.MustParseGTID(flavor, cfg.GtidString)\n// after\ngtid, err := replication.ParseGTID(flavor, cfg.GtidString)\nif err != nil {\n\treturn vterrors.Wrapf(err, \"invalid GTID %q for flavor %s\", cfg.GtidString, flavor)\n}","handlingStrategy":"validation","validationCode":"if _, err := replication.ParseGTID(flavor, value); err != nil {\n\treturn err\n}","typeGuard":null,"tryCatchPattern":"func safeParseGTID(flavor, value string) (gtid replication.GTID, err error) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\terr = fmt.Errorf(\"MustParseGTID panicked: %v\", r)\n\t\t}\n\t}()\n\treturn replication.MustParseGTID(flavor, value), nil\n}","preventionTips":["Reserve Must* functions for compile-time constants and tests","Pre-parse user/config input with ParseGTID","Verify flavor matches the source MySQL server type"],"tags":["panic","gtid","parsing","mysql"],"backgroundTag":"invalid-gtid-format","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}