{"record":{"id":"906abf2a3d431149","repo":"vitessio/vitess","slug":"unknown-gc-state-v","errorCode":null,"errorMessage":"Unknown GC state: %v","messagePattern":"Unknown GC state: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/schema/tablegc.go","lineNumber":88,"sourceCode":"\tgcStatesTableHints[DropTableGCState] = InternalTableGCDropHint\n\tfor _, gcState := range []TableGCState{HoldTableGCState, PurgeTableGCState, EvacTableGCState, DropTableGCState} {\n\t\tgcStates[string(gcState)] = gcState\n\t\tgcStates[gcState.TableHint().String()] = gcState\n\t}\n}\n\n// generateGCTableName creates a GC table name, based on desired state and time, and with optional preset UUID.\n// If uuid is given, then it must be in GC-UUID format. If empty, the function auto-generates a UUID.\nfunc generateGCTableName(state TableGCState, uuid string, t time.Time) (tableName string, err error) {\n\tfor k, v := range gcStates {\n\t\tif v != state {\n\t\t\tcontinue\n\t\t}\n\t\tif len(k) == 3 && k != string(state) { // the \"new\" format\n\t\t\treturn GenerateInternalTableName(k, uuid, t)\n\t\t}\n\t}\n\treturn \"\", fmt.Errorf(\"Unknown GC state: %v\", state)\n}\n\n// GenerateGCTableName creates a GC table name, based on desired state and time, and with random UUID\nfunc GenerateGCTableName(state TableGCState, t time.Time) (tableName string, err error) {\n\treturn generateGCTableName(state, \"\", t)\n}\n\n// AnalyzeGCTableName analyzes a given table name to see if it's a GC table, and if so, parse out\n// its state, uuid, and timestamp\nfunc AnalyzeGCTableName(tableName string) (isGCTable bool, state TableGCState, uuid string, t time.Time, err error) {\n\t// Try new naming format (e.g. `_vt_hld_6ace8bcef73211ea87e9f875a4d24e90_20200915120410_`):\n\t// The new naming format is accepted in v19, and actually _used_ in v20\n\tif isInternal, hint, uuid, t, err := AnalyzeInternalTableName(tableName); isInternal {\n\t\tgcState, ok := gcStates[hint]\n\t\treturn ok, gcState, uuid, t, err\n\t}\n\treturn false, state, uuid, t, nil\n}","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/schema/tablegc.go#L70-L106","documentation":"generateGCTableName maps a TableGCState to its 3-character name-format code by scanning the gcStates map; if no entry's key matches the requested state, it fails with this error. It means the caller asked for a GC table name for a state that has no corresponding table-name code (e.g. an invalid or non-representable TableGCState value).","triggerScenarios":"Calling GenerateGCTableName(state, t) or GenerateRenameStatementWithUUID with a TableGCState that is not one of the defined gcStates keys (e.g. a zero-value TableGCState(\"\") or a corrupted/deserialized state).","commonSituations":"Deserializing a GC state from config or a DB column where the string didn't match enum values; constructing TableGCState from raw ints; passing an uninitialized state variable.","solutions":["Pass one of the valid TableGCState values (e.g. TunableGCStates entries like hold/purge/drop states).","Validate/parse the state with ParseGCLifecycle or check membership in gcStates before generating a name.","Check where the state value originated (config/env/DB) for typos or empty strings."],"exampleFix":"// before\nstate := schema.TableGCState(\"\")\nname, err := schema.GenerateGCTableName(state, time.Now())\n// after\nstate := schema.HoldTableGCState\nname, err := schema.GenerateGCTableName(state, time.Now())","handlingStrategy":"validation","validationCode":"switch state {\ncase schema.HoldTableGCState, schema.PurgeTableGCState, schema.DropTableGCState, schema.EvacTableGCState:\n    // ok\ndefault:\n    // reject before calling GenerateGCTableName\n}","typeGuard":"func knownGCState(s schema.TableGCState) bool {\n    for _, k := range schema.TunableGCStates {\n        if k == s { return true }\n    }\n    return false\n}","tryCatchPattern":"name, err := schema.GenerateGCTableName(state, now)\nif err != nil {\n    return fmt.Errorf(\"gc table name generation failed: %w\", err)\n}","preventionTips":["Only pass named TableGCState constants, never raw casts of strings/ints.","Validate states parsed from config/DB against the enum before use.","Guard against zero-value TableGCState in struct initializers."],"tags":["schema","gc","enum","table-gc"],"backgroundTag":"unknown-gc-state","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}