immich-app/immich · warning · BadRequestException

At least two people are required for merging

Error message

At least two people are required for merging

What it means

mergePeople requires at least two person IDs because merging means collapsing one or more source people into a primary. With fewer than two IDs there is nothing to merge, so it throws BadRequestException('At least two people are required for merging') before any access checks.

Solutions

  1. Include at least two person IDs: the primary person (in the URL) plus at least one source person in the ids array.
  2. Select the duplicate people in the UI before clicking merge.
  3. Fix client scripts to validate ids.length >= 2 before calling the API.
  4. If you only have one person, there is nothing to merge — remove the duplicate expectation from your workflow.

Example fix

// before
await api.peopleApi.mergePerson({ id: primaryId, mergePersonDto: { ids: [primaryId] } }); // 1 id -> 400
// after
const ids = [duplicateId1, duplicateId2];
if (ids.length >= 2) {
  await api.peopleApi.mergePerson({ id: primaryId, mergePersonDto: { ids } });
}
Defensive patterns

Strategy: validation

Validate before calling

if (!Array.isArray(ids) || ids.length < 2) {
  throw new Error('Select at least two people to merge');
}

Try / catch

try {
  await api.peopleApi.mergePerson({ id: primaryId, mergePersonDto: { ids } });
} catch (e) {
  if (e.status === 400 && String(e.message).includes('At least two people are required')) {
    // re-open selection UI
  } else throw e;
}

Prevention

When it happens

Trigger: POST /api/people/{id}/merge (or the merge endpoint) with a MergePersonDto whose ids array has 0 or 1 entries — e.g. only the primary person selected with no sources, or an empty selection.

Common situations: UI state where checkboxes were cleared before submitting, API scripts calling merge with a single ID, or client bugs sending ids=[primaryId] only.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of immich-app/immich@f48d4b3321 (2026-09-15). Data as JSON: /api/errors/864dae4179f5d240. Report an issue: GitHub.

Appendix: source

Thrown at server/src/services/person.service.ts:589

    return JobStatus.Success;
  }

  @OnJob({ name: JobName.PersonFileMigration, queue: QueueName.Migration })
  async handlePersonMigration({ ownerId, personGroupId }: JobOf<JobName.PersonFileMigration>): Promise<JobStatus> {
    const person = await this.personRepository.getByGroupId({ ownerId, personGroupId });
    if (!person) {
      return JobStatus.Failed;
    }

    await this.storageCore.movePersonFile(person, PersonPathType.Face);

    return JobStatus.Success;
  }

  async mergePeople(auth: AuthDto, { ids }: MergePersonDto): Promise<BulkIdResponseDto[]> {
    if (ids.length < 2) {
      throw new BadRequestException('At least two people are required for merging');
    }

    if (new Set(ids).size !== ids.length) {
      throw new BadRequestException('Cannot merge a person into themselves');
    }

    const results: BulkIdResponseDto[] = [];

    const allowedIds = await this.checkAccess({ auth, permission: Permission.PersonMerge, ids });

    const peopleMap: Record<string, Selectable<PersonTable>[]> = {};

    for (const mergePerson of await this.personRepository.getForMergePerson(ids)) {
      if (!peopleMap[mergePerson.personGroupId]) {
        peopleMap[mergePerson.personGroupId] = [];
      }
      peopleMap[mergePerson.personGroupId].push(mergePerson);
    }

View on GitHub (pinned to f48d4b3321)