{"record":{"id":"ecba51fe57c382d6","repo":"bytebase/bytebase","slug":"expecting-variable-s-but-got-s","errorCode":null,"errorMessage":"expecting variable %s, but got %s","messagePattern":"expecting variable (.+?), but got (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/plugin/db/mysql/sync.go","lineNumber":153,"sourceCode":"\t\tMetadata: &storepb.Instance{\n\t\t\tMysqlLowerCaseTableNames: lowerCaseTableNames,\n\t\t\tRoles:                    instanceRoles,\n\t\t},\n\t}, nil\n}\n\nfunc (d *Driver) getServerVariable(ctx context.Context, varName string) (string, error) {\n\tdb := d.GetDB()\n\tquery := fmt.Sprintf(\"SHOW VARIABLES LIKE '%s'\", varName)\n\tvar varNameFound, value string\n\tif err := db.QueryRowContext(ctx, query).Scan(&varNameFound, &value); err != nil {\n\t\tif err == sql.ErrNoRows {\n\t\t\treturn \"\", common.FormatDBErrorEmptyRowWithQuery(query)\n\t\t}\n\t\treturn \"\", util.FormatErrorWithQuery(err, query)\n\t}\n\tif varName != varNameFound {\n\t\treturn \"\", errors.Errorf(\"expecting variable %s, but got %s\", varName, varNameFound)\n\t}\n\treturn value, nil\n}\n\nfunc containsInvisibleChars(data []byte) bool {\n\t// Iterate over the byte slice as runes\n\tfor len(data) > 0 {\n\t\tr, size := utf8.DecodeRune(data)\n\t\tif r == utf8.RuneError && size == 1 {\n\t\t\t// If the byte slice contains invalid UTF-8 characters, treat it as invisible\n\t\t\treturn true\n\t\t}\n\t\t// Check if the rune is not printable\n\t\tif !unicode.IsPrint(r) {\n\t\t\treturn true\n\t\t}\n\t\t// Move to the next rune\n\t\tdata = data[size:]","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/bytebase/bytebase/blob/1870550677fe08f0d2a78c07acd27541464eb945/backend/plugin/db/mysql/sync.go#L135-L171","documentation":"In getServerVariable, after querying @@variable_name, the code verifies the returned Variable_name column matches the requested name. This error fires when the server echoes back a different variable name than the one asked for — meaning the variable does not exist (server returned an unexpected/empty mapping) or the result row is misaligned. It is an invariant check on server variables during SyncInstance.","triggerScenarios":"Requesting a server variable (e.g. version_comment, max_connections) that the connected MySQL-compatible server (MariaDB, OceanBase, TiDB) does not define, so the result set returns a different name or the code's expectation no longer matches the dialect.","commonSituations":"Syncing a MariaDB/OceanBase/TiDB instance whose variable set differs from vanilla MySQL; MySQL version changes renaming/removing variables; typos in the variable name passed to getServerVariable.","solutions":["Run SELECT @@<variable> manually on the server to confirm the variable exists","Check the server dialect/version; use a dialect-appropriate variable or skip it when absent","Verify the variable name string passed into getServerVariable matches the SQL query construction exactly","Add version-aware variable lookup so unsupported variables are skipped instead of erroring"],"exampleFix":"// before\nif varName != varNameFound {\n    return \"\", errors.Errorf(\"expecting variable %s, but got %s\", varName, varNameFound)\n}\n// after\nif varNameFound == \"\" {\n    return \"\", nil // variable not supported by this server; use default\n}\nif varName != varNameFound {\n    return \"\", errors.Errorf(\"expecting variable %s, but got %s\", varName, varNameFound)\n}","handlingStrategy":"validation","validationCode":"var supported bool\ndb.QueryRow(\"SELECT COUNT(*) FROM information_schema.variables_info WHERE variable_name = ?\", varName).Scan(&supported)\n// if !supported, skip the variable or use a default instead of erroring","typeGuard":null,"tryCatchPattern":"value, err := getServerVariable(ctx, db, \"version_comment\")\nif err != nil && strings.Contains(err.Error(), \"expecting variable\") {\n    value = \"\" // treat unsupported variable as default\n}","preventionTips":["Confirm each queried variable exists on the target dialect (MySQL vs MariaDB vs OceanBase/TiDB)","Build a per-dialect variable map and skip unknown variables gracefully","Test instance sync against all supported MySQL-compatible dialects","Double-check variable names when adding new sync checks"],"tags":["mysql","server-variable","sync"],"backgroundTag":"unexpected-response-shape","analyzedSha":"1870550677fe08f0d2a78c07acd27541464eb945","analyzedAt":"2026-09-06T21:16:13.665Z","contentChangedAt":"2026-09-06T21:16:13.665Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}