{"record":{"id":"e23aea3896279d94","repo":"vitessio/vitess","slug":"candidatepromotionrule-v-not-supported-yet","errorCode":null,"errorMessage":"CandidatePromotionRule: %v not supported yet","messagePattern":"CandidatePromotionRule: (.+?) not supported yet","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtctl/reparentutil/promotionrule/promotion_rule.go","lineNumber":63,"sourceCode":"\treturn []CandidatePromotionRule{Must, Prefer, Neutral, PreferNot, MustNot}\n}\n\nfunc (r *CandidatePromotionRule) BetterThan(other CandidatePromotionRule) bool {\n\totherOrder, ok := promotionRuleOrderMap[other]\n\tif !ok {\n\t\treturn false\n\t}\n\treturn promotionRuleOrderMap[*r] < otherOrder\n}\n\n// Parse returns a CandidatePromotionRule by name.\n// It returns an error if there is no known rule by the given name.\nfunc Parse(ruleName string) (CandidatePromotionRule, error) {\n\tswitch ruleName {\n\tcase \"prefer\", \"neutral\", \"prefer_not\", \"must_not\":\n\t\treturn CandidatePromotionRule(ruleName), nil\n\tcase \"must\":\n\t\treturn CandidatePromotionRule(\"\"), fmt.Errorf(\"CandidatePromotionRule: %v not supported yet\", ruleName)\n\tdefault:\n\t\treturn CandidatePromotionRule(\"\"), fmt.Errorf(\"Invalid CandidatePromotionRule: %v\", ruleName)\n\t}\n}\n","sourceCodeStart":45,"sourceCodeEnd":68,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtctl/reparentutil/promotionrule/promotion_rule.go#L45-L68","documentation":"promotionrule.Parse maps a string CandidatePromotionRule to its enum value. The rule 'must' is recognized syntactically but explicitly rejected as not yet implemented, with a dedicated message distinguishing it from fully unknown names.","triggerScenarios":"A tablet's CandidatePromotionRule field (from tablet tags/labels, e.g. promoted via ERS/PRS candidate selection) is set to 'must' and reparentutil parses it during EmergencyReparentShard or PlannedReparentShard candidate evaluation.","commonSituations":"Operator tagged a tablet with promotion rule 'must' expecting hard requirement semantics; tooling or automation copied 'must' from other orchestrator conventions; docs/config examples using unsupported value.","solutions":["Change the tablet's candidate promotion rule label to a supported value: 'prefer', 'neutral', 'prefer_not', or 'must_not'","If 'must' semantics are needed, use 'prefer' plus explicit PRS to that tablet (PlannedReparentShard --new-primary)","Implement 'must' support in promotionrule.Parse if your fork requires it, or file/track the upstream feature"],"exampleFix":"// before\nvtctldclient Tablet ... label promotion_rule=must\n// after\nvtctldclient Tablet ... label promotion_rule=prefer_not  # or prefer/neutral","handlingStrategy":"validation","validationCode":"// Validate promotion rule labels before reparent\nswitch rule := strings.ToLower(label); rule {\ncase \"prefer\", \"neutral\", \"prefer_not\", \"must_not\":\n\t// ok\ncase \"must\":\n\treturn fmt.Errorf(\"'must' is not supported; use 'prefer' plus explicit PRS\")\ndefault:\n\treturn fmt.Errorf(\"invalid promotion rule %q\", label)\n}","typeGuard":"func isValidPromotionRule(s string) bool {\n\tswitch s {\n\tcase \"prefer\", \"neutral\", \"prefer_not\", \"must_not\":\n\t\treturn true\n\t}\n\treturn false\n}","tryCatchPattern":"if _, err := promotionrule.Parse(rule); err != nil {\n\tif strings.Contains(err.Error(), \"not supported yet\") {\n\t\t// 'must' requested: downgrade to 'prefer' or fail the workflow early\n\t}\n}","preventionTips":["Restrict tablet label values to the four supported rules","Never use 'must' until upstream implements it","Validate labels at set-time, not reparent-time"],"tags":["promotion-rule","reparent","config"],"backgroundTag":"unsupported-promotion-rule","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}