{"record":{"id":"c5611b337f81fd5f","repo":"vitessio/vitess","slug":"forgetinstance-empty-tabletalias","errorCode":null,"errorMessage":"ForgetInstance(): empty tabletAlias","messagePattern":"ForgetInstance\\(\\): empty tabletAlias","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtorc/inst/instance_dao.go","lineNumber":1152,"sourceCode":"\t}\n\treturn ExecDBWriteFunc(writeFunc)\n}\n\n// InstanceIsForgotten returns true if an instance was forgotten.\nfunc InstanceIsForgotten(tabletAlias *topodatapb.TabletAlias) bool {\n\tinitForgetAliasesCache()\n\ttabletAliasString := topoproto.TabletAliasString(tabletAlias)\n\t_, found := forgetAliases.Get(tabletAliasString)\n\treturn found\n}\n\n// ForgetInstance removes an instance entry from the vtorc backed database.\n// It may be auto-rediscovered through topology or requested for discovery by multiple means.\nfunc ForgetInstance(tabletAlias *topodatapb.TabletAlias) error {\n\tif tabletAlias == nil {\n\t\terrMsg := \"ForgetInstance(): empty tabletAlias\"\n\t\tlog.Error(errMsg)\n\t\treturn errors.New(errMsg)\n\t}\n\tinitForgetAliasesCache()\n\ttabletAliasString := topoproto.TabletAliasString(tabletAlias)\n\tforgetAliases.Set(tabletAliasString, true, cache.DefaultExpiration)\n\tlog.Info(fmt.Sprintf(\"Forgetting: %v\", tabletAliasString))\n\n\t// Remove this tablet from errant GTID count metric.\n\tcurrentErrantGTIDCount.Reset(tabletAliasString)\n\n\t// Drop any shard-peer health reports from this tablet so a deleted observer\n\t// stops counting toward the quorum denominator immediately.\n\tRemoveShardPeerObserver(tabletAliasString)\n\n\t// Delete from the 'vitess_tablet' table.\n\t_, err := db.ExecVTOrc(`DELETE FROM\n\t\t\tvitess_tablet\n\t\tWHERE\n\t\t\talias = ?`,","sourceCodeStart":1134,"sourceCodeEnd":1170,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtorc/inst/instance_dao.go#L1134-L1170","documentation":"ForgetInstance validates that a non-nil tablet alias was supplied before removing the tablet entry from the vtorc database. A nil alias identifies nothing, so the operation is rejected with this error. It is also logged via log.Error.","triggerScenarios":"Calling ForgetInstance(nil) — directly or from refreshTablets — when the alias came from a failed topo read or an unset variable.","commonSituations":"refreshTablets enumerating tablets when the topo server intermittently returns nil aliases; cleanup scripts calling ForgetInstance with a variable that was never populated.","solutions":["Fix the upstream code path that produced the nil alias.","Add a nil check before calling ForgetInstance and skip/log instead.","If a tablet should be forgotten, obtain its alias from the topo server (topoproto.TabletAliasString for display) and pass the real alias."],"exampleFix":"// before\nerr := inst.ForgetInstance(alias) // alias may be nil\n// after\nif alias != nil {\n    err := inst.ForgetInstance(alias)\n}","handlingStrategy":"validation","validationCode":"if alias == nil {\n    return errors.New(\"ForgetInstance requires a non-nil tablet alias\")\n}","typeGuard":"func forgettable(a *topodatapb.TabletAlias) bool {\n    return a != nil && a.Cell != \"\" && a.Uid != 0\n}","tryCatchPattern":"err := inst.ForgetInstance(alias)\nif err != nil && strings.Contains(err.Error(), \"empty tabletAlias\") {\n    log.Warn(\"forget skipped: nil alias\")\n}","preventionTips":["Validate aliases at the boundary of topo reads before any mutation APIs.","Never propagate nil aliases through cleanup/recovery code paths."],"tags":["vtorc","forget-instance","nil-argument","validation"],"backgroundTag":"nil-argument","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}