temporalio/temporal · error

rowsAffected returned %v shards instead of one

Error message

rowsAffected returned %v shards instead of one

What it means

Same create-shard verification path: the INSERT of a shard row must affect exactly 1 row; any other count causes this error. It guarantees one canonical shard row per shardID, so a non-1 count is treated as a storage invariant violation.

Source

Thrown at common/persistence/sql/shard.go:109

			m.logger,
		); err != nil {
			return err
		}
		result, err := tx.UpdateShards(ctx, &sqlplugin.ShardsRow{
			ShardID:      request.ShardID,
			RangeID:      request.RangeID,
			Data:         request.ShardInfo.Data,
			DataEncoding: request.ShardInfo.EncodingType.String(),
		})
		if err != nil {
			return err
		}
		rowsAffected, err := result.RowsAffected()
		if err != nil {
			return fmt.Errorf("rowsAffected returned error for shardID %v: %v", request.ShardID, err)
		}
		if rowsAffected != 1 {
			return fmt.Errorf("rowsAffected returned %v shards instead of one", rowsAffected)
		}
		return nil
	})
}

func (m *sqlShardStore) AssertShardOwnership(
	ctx context.Context,
	request *persistence.AssertShardOwnershipRequest,
) error {
	// AssertShardOwnership is not implemented for sql shard store
	return nil
}

// initiated by the owning shard
func lockShard(
	ctx context.Context,
	tx sqlplugin.Tx,
	shardID int32,

View on GitHub (pinned to bde624efd1)

Solutions

  1. Query the shards table for the given shardID to see whether the row exists; delete duplicates if more than one.
  2. Check for triggers or modified schema affecting the shards table.
  3. Retry the operation; if the shard already exists, the normal read path (GetShard/ownership checks) will handle it.
  4. Verify driver and backend compatibility; test the same INSERT manually against the database.
Defensive patterns

Strategy: validation

Validate before calling

var n int
db.QueryRow("SELECT COUNT(*) FROM shards WHERE shard_id = ?", shardID).Scan(&n)
// n should be 0 before creation; n > 1 means duplicates already exist

Try / catch

if strings.Contains(err.Error(), "shards instead of one") {
    // inspect shards table for the shardID; repair duplicates, then retry
}

Prevention

When it happens

Trigger: Creating a shard where result.RowsAffected() returns 0 (row not actually inserted) or >1 (e.g., driver counting quirks).

Common situations: Replication setups reporting odd affected-row counts; triggers on the shards table; silent insert suppression from stale connections or unusual driver semantics.

Related errors


AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01). Data as JSON: /api/errors/14369541d8c54181. Report an issue: GitHub.