{"record":{"id":"13121ee7d96d2a69","repo":"vitessio/vitess","slug":"failed-to-lock-s-s-if-you-really-want-to-delete","errorCode":null,"errorMessage":"failed to lock %s/%s; if you really want to delete this shard, re-run with Force=true: %w","messagePattern":"failed to lock (.+?)/(.+?); if you really want to delete this shard, re-run with Force=true: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtctl/grpcvtctldserver/topo.go","lineNumber":51,"sourceCode":")\n\nfunc deleteShard(ctx context.Context, ts *topo.Server, keyspace string, shard string, recursive bool, evenIfServing bool, force bool) (err error) {\n\tspan, ctx := trace.NewSpan(ctx, \"VtctldServer.deleteShard\")\n\tdefer span.Finish()\n\n\tspan.Annotate(\"keyspace\", keyspace)\n\tspan.Annotate(\"shard\", shard)\n\tspan.Annotate(\"recursive\", recursive)\n\tspan.Annotate(\"even_if_serving\", evenIfServing)\n\tspan.Annotate(\"force\", force)\n\n\tlctx, unlock, lerr := ts.LockShard(ctx, keyspace, shard, \"DeleteShard\")\n\tswitch {\n\tcase lerr == nil:\n\t\t// We locked the shard, all good\n\t\tctx = lctx\n\tcase !force:\n\t\treturn fmt.Errorf(\"failed to lock %s/%s; if you really want to delete this shard, re-run with Force=true: %w\", keyspace, shard, lerr)\n\tdefault:\n\t\t// Failed to lock, but force=true. Warn and continue\n\t\tlog.Warn(fmt.Sprintf(\"%s: failed to lock shard %s/%s for deletion, but force=true, proceeding anyway ...\", lerr, keyspace, shard))\n\t}\n\n\tif unlock != nil {\n\t\tdefer func() {\n\t\t\t// Attempting to unlock a shard we successfully deleted results in\n\t\t\t// ts.unlockShard returning an error, which can make the overall\n\t\t\t// RPC _seem_ like it failed.\n\t\t\t//\n\t\t\t// So, we do this extra checking to allow for specifically this\n\t\t\t// scenario to result in \"success.\"\n\t\t\torigErr := err\n\t\t\tunlock(&err)\n\t\t\tif origErr == nil && topo.IsErrType(err, topo.NoNode) {\n\t\t\t\terr = nil\n\t\t\t}","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtctl/grpcvtctldserver/topo.go#L33-L69","documentation":"deleteShard tries to take a shard-level topo lock (LockShard with action DeleteShard) before deleting. If locking fails and force is false, deletion is refused with \"failed to lock %s/%s; if you really want to delete this shard, re-run with Force=true: %w\", protecting against concurrent operations on the shard.","triggerScenarios":"DeleteShard/DeleteKeyspace while another operation holds the shard lock (stale lock from a crashed job, or a live PRS/backup), and Force is not set.","commonSituations":"Aborted vtctl run left a lock entry in the topo; another operator or workflow is actively working on the shard; lock TTL not yet expired.","solutions":["Wait for the concurrent operation to finish and its lock to be released, then re-run without Force.","Verify nothing is actually operating on the shard, then re-run with Force=true to bypass the lock.","Inspect the topo lock node (GetShardLockInfo / topo lock paths) to identify the lock holder and clear a stale lock."],"exampleFix":"// before\nvtctldclient DeleteShard commerce/0\n// error: failed to lock commerce/0 ...\n// after (only if safe — no active operations on the shard)\nvtctldclient DeleteShard commerce/0 --force","handlingStrategy":"try-catch","validationCode":"lctx, unlock, err := ts.LockShard(ctx, ks, shard, \"check-only\"); if err != nil { /* lock is held: find holder via topo lock info before destructive ops */ } else { unlock(&err) }","typeGuard":null,"tryCatchPattern":"err := deleteShard(ctx, ks, shard, false); if err != nil && strings.Contains(err.Error(), \"failed to lock\") { /* confirm no active op on the shard, then retry with Force=true or wait for lock expiry */ }","preventionTips":["Never force-delete while reparents/backups may be running","Check shard lock info before destructive commands","Use short-lived operations so stale locks expire quickly","Only pass Force=true after verifying the lock holder is dead"],"tags":["topo","lock","shard","concurrency"],"backgroundTag":"shard-lock-held","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}