{"record":{"id":"3f3159f88cb4f675","repo":"vitessio/vitess","slug":"can-t-lock-shard-shard-name-is-unspecified","errorCode":null,"errorMessage":"can't lock shard: shard name is unspecified","messagePattern":"can't lock shard: shard name is unspecified","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtorc/logic/topology_recovery.go","lineNumber":246,"sourceCode":"\turgentOperations = cache.New(urgentOperationsInterval, 2*urgentOperationsInterval)\n\tgo initializeTopologyRecoveryPostConfiguration()\n}\n\nfunc initializeTopologyRecoveryPostConfiguration() {\n\tconfig.WaitForConfigurationToBeLoaded()\n}\n\nfunc getLockAction(tabletAlias *topodatapb.TabletAlias, code inst.AnalysisCode) string {\n\treturn fmt.Sprintf(\"VTOrc Recovery for %v on %v\", code, topoproto.TabletAliasString(tabletAlias))\n}\n\n// LockShard locks the keyspace-shard preventing others from performing conflicting actions.\nfunc LockShard(ctx context.Context, keyspace, shard, lockAction string) (context.Context, func(*error), error) {\n\tif keyspace == \"\" {\n\t\treturn nil, nil, errors.New(\"can't lock shard: keyspace is unspecified\")\n\t}\n\tif shard == \"\" {\n\t\treturn nil, nil, errors.New(\"can't lock shard: shard name is unspecified\")\n\t}\n\tif hasReceivedSIGTERM.Load() > 0 {\n\t\treturn nil, nil, errors.New(\"can't lock shard: SIGTERM received\")\n\t}\n\n\tstartTime := time.Now()\n\tdefer func() {\n\t\tlockTime := time.Since(startTime)\n\t\tshardLockTimings.Add(\"Lock\", lockTime)\n\t}()\n\n\tshardsLockCounter.Add(1)\n\tctx, unlock, err := ts.TryLockShard(ctx, keyspace, shard, lockAction)\n\tif err != nil {\n\t\tshardsLockCounter.Add(-1)\n\t\treturn nil, nil, err\n\t}\n\treturn ctx, func(e *error) {","sourceCodeStart":228,"sourceCodeEnd":264,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtorc/logic/topology_recovery.go#L228-L264","documentation":"LockShard acquires a cluster-wide lock on a keyspace-shard so only one recovery/action touches it at a time. This error is thrown when the shard argument is an empty string, meaning the caller tried to lock a shard without naming it. It is a precondition failure, not a lock-contention error.","triggerScenarios":"executeCheckAndRecoverFunction (or any caller of logic.LockShard) passes an empty shard value, typically because the recovery analysisEntry had no AnalyzedShard set (e.g. keyspace-wide or non-shard-specific analysis).","commonSituations":"Running vtorc recovery for an analysis entry that was computed at cluster level rather than shard level; a nil/empty shard field propagated from a detection entry; custom recovery automation calling LockShard with an incomplete keyspace/shard pair.","solutions":["Check the analysisEntry that led to the recovery; ensure AnalyzedShard is populated before recovery execution","Verify the topology detection code that produced the entry sets shard information","For manual/programmatic calls, pass a valid shard name from the keyspace's shard set"],"exampleFix":"// before\nctx, unlock, err := LockShard(ctx, keyspace, \"\", lockAction)\n// after\nif shard == \"\" {\n    return fmt.Errorf(\"cannot lock: shard not resolved for keyspace %s\", keyspace)\n}\nctx, unlock, err := LockShard(ctx, keyspace, shard, lockAction)","handlingStrategy":"validation","validationCode":"if keyspace == \"\" || shard == \"\" {\n    return fmt.Errorf(\"LockShard requires non-empty keyspace and shard, got %q/%q\", keyspace, shard)\n}\nctx, unlock, err := logic.LockShard(ctx, keyspace, shard, lockAction)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Resolve keyspace/shard from the analysis entry before initiating recovery","Log the full analysis entry when it lacks shard info","Validate analysis entries at ingestion, not at lock time"],"tags":["vtorc","shard-lock","invalid-argument"],"backgroundTag":"missing-required-argument","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}