{"record":{"id":"c1607c494fb18112","repo":"bytebase/bytebase","slug":"failed-to-parse-mysql-version-s-to-semantic-versi","errorCode":null,"errorMessage":"failed to parse MySQL version %s to semantic version","messagePattern":"failed to parse MySQL version (.+?) to semantic version","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/plugin/db/mysql/sync.go","lineNumber":202,"sourceCode":"\t}\n\n\treturn isoBytes, nil\n}\n\n// SyncDBSchema syncs a single database schema.\nfunc (d *Driver) SyncDBSchema(ctx context.Context) (*storepb.DatabaseSchemaMetadata, error) {\n\tschemaMetadata := &storepb.SchemaMetadata{\n\t\tName: \"\",\n\t}\n\n\t// Query MySQL version\n\tversion, rest, err := d.getVersion(ctx)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tsemVersion, err := semver.Make(version)\n\tif err != nil {\n\t\treturn nil, errors.Wrapf(err, \"failed to parse MySQL version %s to semantic version\", version)\n\t}\n\tatLeast800 := semVersion.GE(semver.MustParse(\"8.0.0\"))\n\tatLeast803 := semVersion.GE(semver.MustParse(\"8.0.3\"))\n\tatLeast8_0_13 := semVersion.GE(semver.MustParse(\"8.0.13\"))\n\tatLeast8_0_16 := semVersion.GE(semver.MustParse(\"8.0.16\"))\n\tatLeast5_7_0 := semVersion.GE(semver.MustParse(\"5.7.0\"))\n\tisMariaDB := strings.Contains(rest, \"MariaDB\")\n\t// Some information_schema features exist only on stock MySQL: compatible engines\n\t// (MariaDB, OceanBase, TiDB) registered as MYSQL report MySQL-like versions but\n\t// lack them, so every stock-only query/decode must share this one predicate.\n\tstockMySQL := isStockMySQL(rest)\n\t// Binary-family (binary charset) literal defaults are reported by\n\t// information_schema.COLUMNS in version-specific encodings that must be decoded to\n\t// the canonical dump form (see canonicalBinaryDefault). The conventions are verified\n\t// for stock MySQL only; MariaDB, OceanBase, and TiDB keep the legacy verbatim path.\n\tbinaryDefaultFmt := binaryDefaultVerbatim\n\tif stockMySQL {\n\t\tif atLeast800 {","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/bytebase/bytebase/blob/1870550677fe08f0d2a78c07acd27541464eb945/backend/plugin/db/mysql/sync.go#L184-L220","documentation":"During schema sync, the MySQL driver reads the server version string (from getVersion, typically `SELECT VERSION()`) and converts it to a semantic version with semver.Make. If the returned string is not a parseable semantic version, the driver aborts the sync because all subsequent feature checks (8.0.x comparisons) depend on it. The original parse error is wrapped with the offending version string.","triggerScenarios":"SyncDBSchema on a MySQL server whose VERSION() output cannot be parsed as a semver: non-standard version strings, forked builds, version strings with unexpected suffixes/prefixes (e.g. '5.5.5-10.1.20-MariaDB', '6.0.11-log' style oddities), or a proxy returning a custom banner.","commonSituations":"Pointing Bytebase at MariaDB, Percona forks with unusual versioning, MySQL-compatible proxies (ProxySQL, Vitess) that rewrite the version string, or cloud servers reporting versions with non-numeric prefixes.","solutions":["Log/inspect the actual version string via `SELECT VERSION()` on the target instance to see what fails to parse.","If it is MariaDB or a fork, use the proper MariaDB driver/connection path instead of the MySQL one.","If a proxy rewrites the version, configure the proxy to pass through a standard MySQL version string.","If the version is standard but has an extra suffix, upgrade the driver/plugin so the version normalization handles it, or patch getVersion to strip the suffix before semver.Make."],"exampleFix":"// before\nsemVersion, err := semver.Make(version)\n// after\nv := version\nif i := strings.IndexAny(v, \"-\"); i >= 0 { v = v[:i] }\nsemVersion, err := semver.Make(v)","handlingStrategy":"validation","validationCode":"var v string\nif err := db.QueryRow(\"SELECT VERSION()\").Scan(&v); err != nil { return err }\nbase := strings.Fields(v)[0]\nif i := strings.Index(base, \"-\"); i >= 0 { base = base[:i] }\nif _, err := semver.Make(base); err != nil { return fmt.Errorf(\"unparseable server version %q\", v) }","typeGuard":null,"tryCatchPattern":"if err != nil {\n  var semErr *semver.ParseError\n  if errors.As(errors.Unwrap(err), &semErr) { /* fallback: treat as unknown version, skip 8.0-only paths */ }\n}","preventionTips":["Pre-check `SELECT VERSION()` parseability before enabling schema sync on a new instance.","Prefer the dedicated MariaDB path for MariaDB servers.","Keep proxies configured to report genuine MySQL version strings."],"tags":["mysql","version-parsing","schema-sync"],"backgroundTag":"invalid-argument-format","analyzedSha":"1870550677fe08f0d2a78c07acd27541464eb945","analyzedAt":"2026-09-06T21:16:13.665Z","contentChangedAt":"2026-09-06T21:16:13.665Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}