immich-app/immich · error · BadRequestException

withPartners is only supported for non-archived…

Error message

withPartners is only supported for non-archived, non-trashed, non-favorited, non-locked assets

What it means

Thrown by TimelineService.timeBucketChecks when dto.withPartners is combined with restricted visibility/favorite/trash filters. Partner timelines are only computed for the base, all-assets view; filtering them by archive, trash, favorite, or locked state is unsupported. It is a 400 BadRequest for an unsupported filter combination.

Solutions

  1. Omit withPartners when querying trash, archive, favorites, or locked visibility
  2. Set visibility/isFavorite/isTrashed to values outside the restricted set (e.g. isFavorite undefined, isTrashed false, visibility not Archive/undefined/Locked)
  3. Fetch partner assets in a separate request without the restricted filters

Example fix

// before
await api.getTimeBuckets({ withPartners: true, isTrashed: true });
// after
await api.getTimeBuckets({ withPartners: true });
const trashed = await api.getTimeBuckets({ isTrashed: true });
Defensive patterns

Strategy: validation

Validate before calling

const restricted =
  visibility === 'locked' || visibility === 'archive' || visibility === undefined ||
  isFavorite === true || isFavorite === false || isTrashed === true;
if (withPartners && restricted) {
  throw new Error('withPartners cannot be combined with archive/trash/favorite/locked filters');
}

Try / catch

try { await api.getTimeBuckets(params); } catch (e) {
  if (e.response?.status === 400 && /withPartners/.test(e.response?.data?.message ?? '')) {
    const { withPartners, ...rest } = params;
    return api.getTimeBuckets(rest); // retry without withPartners
  }
  throw e;
}

Prevention

When it happens

Trigger: GET /api/timeline/buckets?withPartners=true together with any of: visibility=locked, visibility=archive or omitted (defaults to archived), isFavorite=true or false, isTrashed=true. All of these trigger the error.

Common situations: Reusing a generic timeline query builder that always sets withPartners=true while also carrying archive/trash filters; UI toggle for partner photos left on while browsing the trash or archive sections.


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

Appendix: source

Thrown at server/src/services/timeline.service.ts:83

      }
    }

    if (dto.tagId) {
      await this.requireAccess({ auth, permission: Permission.TagRead, ids: [dto.tagId] });
    }

    if (auth.sharedLink && !auth.sharedLink.showExif) {
      dto.withCoordinates = false;
    }

    if (dto.withPartners) {
      const isRequestedLocked = dto.visibility === AssetVisibility.Locked;
      const isRequestedArchived = dto.visibility === AssetVisibility.Archive || dto.visibility === undefined;
      const isRequestedFavorite = dto.isFavorite === true || dto.isFavorite === false;
      const isRequestedTrash = dto.isTrashed === true;

      if (isRequestedLocked || isRequestedArchived || isRequestedFavorite || isRequestedTrash) {
        throw new BadRequestException(
          'withPartners is only supported for non-archived, non-trashed, non-favorited, non-locked assets',
        );
      }
    }
  }
}

View on GitHub (pinned to e55ac299a4)