Repository: valkey-io/valkey
File: src/cluster_migrateslots.c (C)

Code before:
    listNode *ln;
    listIter li;
    listRewind(server.cluster->slot_migration_jobs, &li);
    while ((ln = listNext(&li)) != NULL) {
        slotMigrationJob *job = ln->value;
        if (job->type != SLOT_MIGRATION_IMPORT) continue;
        if (isSlotMigrationJobFinished(job)) continue;
        if (isSlotInSlotRanges(slot, job->slot_ranges)) return true;
    }
    return false;
}

/* Sent by the source to the target to initiate the AOF formatted snapshot.
 * Note that if there is an error in the request, we send a fail message in
 * order to prevent infinite retry in the case of incompatibility.
 *
 * CLUSTER SYNCSLOTS ESTABLISH is the only CLUSTER SYNCSLOTS subcommand that
 * will return a reply. Errors are written from the perspective of the end user
 * to help with debugging migrations. */
void clusterCommandSyncSlotsEstablish(client *c) {
    char *name = NULL;
    clusterNode *source_node = NULL;
    clusterNode *owning_node = NULL;
    list *slot_ranges = NULL;

    if (moduleVerifyAllModulesAllowAtomicSlotMigrationOrReply(c) == C_ERR) {
        return;
    }

    if (!nodeIsPrimary(server.cluster->myself)) {
        addReplyError(c, "Target node is not a primary");
        return;
    }

    if (isAnySlotInManualImportingState() ||
        isAnySlotInManualMigratingState()) {
        addReplyError(c, "A slot on the target node is being manually imported "
                         "or migrated");
        return;
    }

    if (c->slot_migration_job) {
        addReplyError(c, "Slot migration client is already a slot migration "
                         "job");
        return;
    }

    /* Order agnostic. We skip unknown key/value pairs forwards
     * compatibility. */
    int i = 3;
    while (i < c->argc) {

Review comment (suggestion):
Question: How will the error propagate back to the user which initially started the slot migration? 
I mean, although it is not expected to have different modules loaded on source and target, it is possible right? (maybe in some migration cases)

Code after:
    listNode *ln;
    listIter li;
    listRewind(server.cluster->slot_migration_jobs, &li);
    while ((ln = listNext(&li)) != NULL) {
        slotMigrationJob *job = ln->value;
        if (job->type != SLOT_MIGRATION_IMPORT) continue;
        if (isSlotMigrationJobFinished(job)) continue;
        if (isSlotInSlotRanges(slot, job->slot_ranges)) return true;
    }
    return false;
}

/* Sent by the source to the target to initiate the AOF formatted snapshot.
 * Note that if there is an error in the request, we send a fail message in
 * order to prevent infinite retry in the case of incompatibility.
 *
 * CLUSTER SYNCSLOTS ESTABLISH is the only CLUSTER SYNCSLOTS subcommand that
 * will return a reply. Errors are written from the perspective of the end user
 * to help with debugging migrations. */
void clusterCommandSyncSlotsEstablish(client *c) {
    char *name = NULL;
    clusterNode *source_node = NULL;
    clusterNode *owning_node = NULL;
    list *slot_ranges = NULL;

    if (moduleVerifyAllAllowAtomicSlotMigrationOrReply(c) == C_ERR) {
        return;
    }

    if (!nodeIsPrimary(server.cluster->myself)) {
        addReplyError(c, "Target node is not a primary");
        return;
    }

    if (isAnySlotInManualImportingState() ||
        isAnySlotInManualMigratingState()) {
        addReplyError(c, "A slot on the target node is being manually imported "
                         "or migrated");
        return;
    }

    if (c->slot_migration_job) {
        addReplyError(c, "Slot migration client is already a slot migration "
                         "job");
        return;
    }

    /* Order agnostic. We skip unknown key/value pairs forwards
     * compatibility. */
    int i = 3;
    while (i < c->argc) {