{"record":{"id":"fc514efcc7069169","repo":"vitessio/vitess","slug":"invalid-flags-for-v-strategy-s","errorCode":null,"errorMessage":"invalid flags for %v strategy: %s","messagePattern":"invalid flags for (.+?) strategy: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/schema/ddl_strategy.go","lineNumber":155,"sourceCode":"\tif _, err := setting.SessionVariables(); err != nil {\n\t\treturn nil, err\n\t}\n\tcutoverAfter, err := setting.ForceCutOverAfter()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tswitch setting.Strategy {\n\tcase DDLStrategyVitess, DDLStrategyOnline:\n\tdefault:\n\t\tif cutoverAfter != 0 {\n\t\t\treturn nil, fmt.Errorf(\"--force-cut-over-after is only valid in 'vitess' strategy. Found %v value in '%v' strategy\", cutoverAfter, setting.Strategy)\n\t\t}\n\t}\n\n\tswitch setting.Strategy {\n\tcase DDLStrategyVitess, DDLStrategyOnline, DDLStrategyMySQL, DDLStrategyDirect:\n\t\tif opts := setting.RuntimeOptions(); len(opts) > 0 {\n\t\t\treturn nil, fmt.Errorf(\"invalid flags for %v strategy: %s\", setting.Strategy, strings.Join(opts, \" \"))\n\t\t}\n\t}\n\n\treturn setting, nil\n}\n\n// isFlag return true when the given string is a CLI flag of the given name\nfunc isFlag(s string, name string) bool {\n\tif s == \"-\"+name {\n\t\treturn true\n\t}\n\tif s == \"--\"+name {\n\t\treturn true\n\t}\n\treturn false\n}\n\n// hasFlag returns true when Options include named flag","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/schema/ddl_strategy.go#L137-L173","documentation":"ParseDDLStrategy collects leftover RuntimeOptions() for the parsed strategy. Strategies vitess, online, mysql, and direct accept no runtime flag options — any unrecognized or unconsumed flags in the ddl_strategy string produce this error listing the offending flags.","triggerScenarios":"SET @@ddl_strategy='vitess --unknown-flag=x' or 'mysql --foo=bar' — options remain after parsing known parameters like --force-cut-over-after, --retain-artifacts, --post-completion-gradient, etc.","commonSituations":"Typos in flag names (--force-cutover-after misspelled); flags from other migration tools (gh-ost options) pasted in; stale flags removed in newer Vitess versions still set by old config; case/space mistakes in parameter names.","solutions":["Remove unknown flags from the ddl_strategy value until only supported ones remain.","Check flag spelling against supported parameters (--force-cut-over-after, --retain-artifacts, --allow-foreign-keys, --post-completion-gradient, etc.).","Update tooling/config that was written for an older Vitess release where the flag existed.","Validate the strategy string with TestParseDDLStrategy-like checks or in a dev environment before production SET statements."],"exampleFix":"// before\nSET @@ddl_strategy='vitess --force-cutover-after=24h'; // typo\n// after\nSET @@ddl_strategy='vitess --force-cut-over-after=24h';","handlingStrategy":"validation","validationCode":"setting, err := schema.ParseDDLStrategy(candidate)\nif err != nil { return fmt.Errorf(\"rejecting ddl_strategy %q: %v\", candidate, err) }","typeGuard":"func hasNoUnknownFlags(s *schema.DDLStrategySetting) bool { return len(s.RuntimeOptions()) == 0 }","tryCatchPattern":"_, err := schema.ParseDDLStrategy(strategyName)\nif err != nil {\n  return fmt.Errorf(\"ddl_strategy flags rejected: %w\", err)\n}","preventionTips":["Spell-check flags against supported parameter list before SET","Test strategy strings in dev first","Remove flags deprecated by newer Vitess releases from config"],"tags":["ddl","online-schema-change","flags"],"backgroundTag":"invalid-ddl-strategy","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}