vitessio/vitess · error · topo.NewError(topo.NoUpdateNeeded)

%w: uid %v is already in use

Error message

%w: uid %v is already in use

What it means

Returned by AddShardSourceShard (vreplication source registration) when the requested UID already exists among the shard's SourceShards. It is wrapped in a topo.NoUpdateNeeded error so the shard's version is not bumped. Each SourceShard entry needs a unique UID for the filtered replication pipeline.

Source

Thrown at go/vt/vtctl/grpcvtctldserver/server.go:4357

	span.Annotate("uid", req.Uid)
	span.Annotate("source_keyspace", req.SourceKeyspace)
	span.Annotate("source_shard", req.SourceShard)
	span.Annotate("keyrange", key.KeyRangeString(req.KeyRange))
	span.Annotate("tables", strings.Join(req.Tables, ","))

	var si *topo.ShardInfo

	ctx, unlock, lockErr := s.ts.LockKeyspace(ctx, req.Keyspace, fmt.Sprintf("SourceShardAdd(%v)", req.Uid))
	if lockErr != nil {
		err = lockErr
		return nil, err
	}
	defer unlock(&err)

	si, err = s.ts.UpdateShardFields(ctx, req.Keyspace, req.Shard, func(si *topo.ShardInfo) error {
		for _, ss := range si.SourceShards {
			if ss.Uid == req.Uid {
				return fmt.Errorf("%w: uid %v is already in use", topo.NewError(topo.NoUpdateNeeded, fmt.Sprintf("%s/%s", req.Keyspace, req.Shard)), req.Uid)
			}
		}

		si.SourceShards = append(si.SourceShards, &topodatapb.Shard_SourceShard{
			Keyspace: req.SourceKeyspace,
			Shard:    req.SourceShard,
			Uid:      req.Uid,
			KeyRange: req.KeyRange,
			Tables:   req.Tables,
		})
		return nil
	})
	if err != nil {
		return nil, err
	}

	resp = &vtctldatapb.SourceShardAddResponse{}
	switch si {

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. List existing SourceShards (`vtctldclient GetShard <keyspace/shard>`) and pick a free UID
  2. Remove the stale SourceShard with RemoveShardSourceShard before re-adding
  3. Re-use the existing SourceShard if it already has the desired configuration instead of adding a duplicate

Example fix

// before
vtctldclient AddShardSourceShard merchant/0 --uid 1 --source merchantcopy/0  # uid 1 already in use
// after
vtctldclient AddShardSourceShard merchant/0 --uid 2 --source merchantcopy/0  # free uid
Defensive patterns

Strategy: validation

Validate before calling

shard, _ := topoServer.GetShard(ctx, keyspace, shardName)
uids := map[uint32]bool{}
for _, ss := range shard.SourceShards { uids[ss.Uid] = true }
if uids[requestedUID] { /* pick another uid or remove existing first */ }

Try / catch

try {
  client.addShardSourceShard(keyspace, shard, sourceKeyspace, sourceShard, uid)
} catch (e) {
  if (String(e).includes('is already in use')) {
    existing = getExistingSourceShard(uid) // reuse or remove first
  } else { throw e }
}

Prevention

When it happens

Trigger: Calling `vtctldclient AddShardSourceShard` with a `--uid` value that collides with an existing SourceShard on the target shard.

Common situations: Re-running a reshard/migration setup script without cleaning up previous SourceShards; picking UIDs manually instead of tracking existing ones; resharding workflow partially completed earlier.

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/5280dfeae9653127. Report an issue: GitHub.