{"record":{"id":"75faefd430c300b8","repo":"vitessio/vitess","slug":"errmysqlshellprecheck","errorCode":"ErrMySQLShellPreCheck","errorMessage":"ErrMySQLShellPreCheck","messagePattern":"ErrMySQLShellPreCheck","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/mysqlctl/mysqlshellbackupengine.go","lineNumber":70,"sourceCode":"\t// location to store the mysql shell backup\n\tmysqlShellBackupLocation = \"\"\n\t// flags passed to the mysql shell utility, used both on dump/restore\n\tmysqlShellFlags = \"--defaults-file=/dev/null --js -h localhost\"\n\t// flags passed to the Dump command, as a JSON string\n\tmysqlShellDumpFlags = `{\"threads\": 4}`\n\t// flags passed to the Load command, as a JSON string\n\tmysqlShellLoadFlags = `{\"threads\": 4, \"loadUsers\": true, \"updateGtidSet\": \"replace\", \"skipBinlog\": true, \"progressFile\": \"\"}`\n\t// drain a tablet when taking a backup\n\tmysqlShellBackupShouldDrain = false\n\t// disable redo logging and double write buffer\n\tmysqlShellSpeedUpRestore = false\n\t// skip the MySQL version compatibility check when restoring from a mysql-shell backup\n\tmysqlShellRestoreSkipVersionCheck = false\n\n\t// use when checking if we need to create the directory on the local filesystem or not.\n\tknownObjectStoreParams = []string{\"s3BucketName\", \"osBucketName\", \"azureContainerName\"}\n\n\tErrMySQLShellPreCheck = errors.New(\"ErrMySQLShellPreCheck\")\n\n\t// internal databases not backed up by MySQL Shell\n\tinternalDBs = []string{\n\t\t\"information_schema\", \"mysql\", \"ndbinfo\", \"performance_schema\", \"sys\",\n\t}\n\t// reserved MySQL users https://dev.mysql.com/doc/refman/8.0/en/reserved-accounts.html\n\treservedUsers = []string{\n\t\t\"mysql.sys@localhost\", \"mysql.session@localhost\", \"mysql.infoschema@localhost\",\n\t}\n)\n\n// MySQLShellBackupManifest represents a backup.\ntype MySQLShellBackupManifest struct {\n\t// BackupManifest is an anonymous embedding of the base manifest struct.\n\t// Note that the manifest itself doesn't fill the Position field, as we have\n\t// no way of fetching that information from mysqlsh at the moment.\n\tBackupManifest\n","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/mysqlctl/mysqlshellbackupengine.go#L52-L88","documentation":"ErrMySQLShellPreCheck is the sentinel error returned when a MySQL Shell-based backup or restore pre-check fails (backupPreCheck/restorePreCheck). Callers are expected to compare with errors.Is to detect this specific condition and take the mysql-shell-specific code path, e.g. skipping the version compatibility check on restore or reporting missing object-store parameters. It is deliberately a sentinel so callers can distinguish pre-check failures from actual backup execution errors.","triggerScenarios":"Calling backupPreCheck or restorePreCheck with mysqlshell engine parameters that fail validation — e.g. missing required object-store parameters (s3BucketName, osBucketName, azureContainerName) or incompatible MySQL version — and TestMySQLShellBackupBackupPreCheck detecting the same conditions.","commonSituations":"Configuring mysqlshell backups with an incomplete storage configuration (no S3 bucket / OS bucket / Azure container); running against a MySQL version unsupported by the configured MySQL Shell dump/load utilities.","solutions":["Use errors.Is(err, mysqlctl.ErrMySQLShellPreCheck) to branch on this error rather than string matching","Fix the pre-check inputs: supply all required object-store parameters for the chosen cloud storage","Verify the MySQL version is compatible with the installed MySQL Shell dump/load utilities before running","Consult the pre-check log messages for the exact parameter that failed"],"exampleFix":"// before\nif err != nil && strings.Contains(err.Error(), \"ErrMySQLShellPreCheck\") { ... }\n// after\nif errors.Is(err, mysqlctl.ErrMySQLShellPreCheck) { /* handle pre-check failure */ }","handlingStrategy":"type-guard","validationCode":"// validate params before invoking the pre-check\nfor _, k := range []string{\"s3BucketName\", \"osBucketName\", \"azureContainerName\"} {\n    if _, ok := params[k]; !ok {\n        return fmt.Errorf(\"missing object store param %q for mysqlshell backup\", k)\n    }\n}","typeGuard":"func isMySQLShellPreCheckErr(err error) bool {\n    return errors.Is(err, mysqlctl.ErrMySQLShellPreCheck)\n}","tryCatchPattern":"err := engine.Backup(ctx, ...)\nif err != nil {\n    if errors.Is(err, mysqlctl.ErrMySQLShellPreCheck) {\n        // fix config/version issues and retry pre-check\n        return handlePreCheckFailure(err)\n    }\n    return err\n}","preventionTips":["Always compare with errors.Is, never string matching","Validate object-store parameters at configuration load time","Check MySQL/MySQL Shell version compatibility before scheduling backups"],"tags":["go","mysqlctl","mysqlshell","sentinel-error","backup-precheck"],"backgroundTag":"mysqlshell-precheck-failed","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}