vitessio/vitess · error · ErrMySQLShellPreCheck
%w: unable to parse JSON of load flags
Error message
%w: unable to parse JSON of load flags
What it means
The mysql-shell load flags (--mysql-shell-load-flags) must be valid JSON because restorePreCheck() unmarshals them into a map. If json.Unmarshal fails, this error wrapping ErrMySQLShellPreCheck is returned and the restore is aborted.
Source
Thrown at go/vt/mysqlctl/mysqlshellbackupengine.go:507
if !isObjectStoreFlags(mysqlShellDumpFlags) {
err := os.MkdirAll(location, 0o750)
if err != nil {
return fmt.Errorf("failure creating directory %s: %w", location, err)
}
}
return nil
}
func (be *MySQLShellBackupEngine) restorePreCheck(ctx context.Context, params RestoreParams) (shouldDeleteUsers bool, err error) {
if mysqlShellFlags == "" {
return shouldDeleteUsers, fmt.Errorf("%w: at least the --js flag is required in the value of the flag --mysql-shell-flags", ErrMySQLShellPreCheck)
}
loadFlags := map[string]any{}
err = json.Unmarshal([]byte(mysqlShellLoadFlags), &loadFlags)
if err != nil {
return false, fmt.Errorf("%w: unable to parse JSON of load flags", ErrMySQLShellPreCheck)
}
if val, ok := loadFlags["updateGtidSet"]; !ok || val != "replace" {
return false, fmt.Errorf("%w: mysql-shell needs to restore with updateGtidSet set to \"replace\" to work with Vitess", ErrMySQLShellPreCheck)
}
if val, ok := loadFlags["progressFile"]; !ok || val != "" {
return false, fmt.Errorf("%w: \"progressFile\" needs to be empty as vitess always starts a restore from scratch", ErrMySQLShellPreCheck)
}
if val, ok := loadFlags["skipBinlog"]; !ok || val != true {
return false, fmt.Errorf("%w: \"skipBinlog\" needs to set to true", ErrMySQLShellPreCheck)
}
if val, ok := loadFlags["loadUsers"]; ok && val == true {
shouldDeleteUsers = true
}
View on GitHub (pinned to 01a25a7d17)
Solutions
- Validate the flag value with `jq . <<< '<value>'` or json.Unmarshal in a scratch program; fix the JSON syntax.
- Escape double quotes properly for the launch layer (systemd Environment=, Helm values, etc.).
- Use a minimal correct value first: '{"updateGtidSet":"replace","progressFile":""}' and add keys incrementally.
Example fix
// before: invalid JSON (single quotes)
--mysql-shell-load-flags "{'updateGtidSet':'replace'}"
// after
--mysql-shell-load-flags "{\"updateGtidSet\":\"replace\",\"progressFile\":\"\"}" Defensive patterns
Strategy: validation
Validate before calling
probe := map[string]any{}
if err := json.Unmarshal([]byte(mysqlShellLoadFlags), &probe); err != nil {
return fmt.Errorf("--mysql-shell-load-flags is not valid JSON: %v", err)
} Try / catch
err := engine.ExecuteRestore(ctx, restoreParams)
if errors.Is(err, mysqlctl.ErrMySQLShellLoadFlagsNotParseable) || strings.Contains(err.Error(), "unable to parse JSON of load flags") {
// fix JSON quoting in the launch layer, then rerun
return err
} Prevention
- Store load flags as a JSON file or single-quoted heredoc to avoid shell quote-stripping.
- Validate the flag with jq or json.Unmarshal in startup scripts.
- Escape double quotes correctly for systemd/Helm/shell layers between config and process.
When it happens
Trigger: ExecuteRestore -> restorePreCheck when --mysql-shell-load-flags contains malformed JSON: single quotes instead of double, trailing commas, unquoted keys, or shell-mangled quoting stripping double quotes.
Common situations: Flags passed through systemd units, Helm charts, or shell scripts where double quotes need escaping and get consumed by an intermediate shell layer; hand-edited config introducing a trailing comma.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- %w: mysql-shell needs to restore with updateGtidSet set to "
- error parsing the json file : %v
- %w: no backup location set via --mysql-shell-backup-location
- %w: at least the --js flag is required in the value of the f
- cannot load vschema file %v for keyspace %v: %v
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/89ee5cab08d230d5.
Report an issue: GitHub.