{"record":{"id":"068ca82e9c3474c4","repo":"immich-app/immich","slug":"withpartners-is-only-supported-for-non-archived-n","errorCode":null,"errorMessage":"withPartners is only supported for non-archived, non-trashed, non-favorited, non-locked assets","messagePattern":"withPartners is only supported for non-archived, non-trashed, non-favorited, non-locked assets","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"server/src/services/timeline.service.ts","lineNumber":83,"sourceCode":"      }\n    }\n\n    if (dto.tagId) {\n      await this.requireAccess({ auth, permission: Permission.TagRead, ids: [dto.tagId] });\n    }\n\n    if (auth.sharedLink && !auth.sharedLink.showExif) {\n      dto.withCoordinates = false;\n    }\n\n    if (dto.withPartners) {\n      const isRequestedLocked = dto.visibility === AssetVisibility.Locked;\n      const isRequestedArchived = dto.visibility === AssetVisibility.Archive || dto.visibility === undefined;\n      const isRequestedFavorite = dto.isFavorite === true || dto.isFavorite === false;\n      const isRequestedTrash = dto.isTrashed === true;\n\n      if (isRequestedLocked || isRequestedArchived || isRequestedFavorite || isRequestedTrash) {\n        throw new BadRequestException(\n          'withPartners is only supported for non-archived, non-trashed, non-favorited, non-locked assets',\n        );\n      }\n    }\n  }\n}\n","sourceCodeStart":65,"sourceCodeEnd":90,"githubUrl":"https://github.com/immich-app/immich/blob/199723261c6ffa897fec8ccdaea6359e39c37cc3/server/src/services/timeline.service.ts#L65-L90","documentation":"Thrown (as BadRequestException) by TimelineService when dto.withPartners is true and the request also filters by locked, archived, favorited, or trashed. Partner inclusion is only meaningful for the default visible timeline, so combining it with any narrowing filter is rejected rather than silently ignored.","triggerScenarios":"GET timeline/buckets or timeline/search with withPartners=true alongside visibility in {Locked, Archive, undefined}, or isFavorite defined, or isTrashed=true.","commonSituations":"Client toggles 'show partners' while a favorites/archive/trash filter is active; default visibility is undefined which also counts as archived-scope and triggers the guard.","solutions":["Disable withPartners when filtering by archive/trash/favorite/locked.","Set visibility=Visible (not undefined) and clear isFavorite/isTrashed before enabling withPartners.","Run two separate requests: one with filters for self, one with withPartners for the partner scope."],"exampleFix":"// before\nbuckets({ withPartners: true, visibility: AssetVisibility.Archive });\n// after\nbuckets({ withPartners: true, visibility: AssetVisibility.Visible, isFavorite: undefined, isTrashed: undefined });","handlingStrategy":"validation","validationCode":"function partnersCompatible(dto: TimelineQueryDto): boolean {\n  if (!dto.withPartners) return true;\n  const archived = dto.visibility === AssetVisibility.Archive || dto.visibility === undefined;\n  return !archived\n    && dto.visibility !== AssetVisibility.Locked\n    && dto.isFavorite === undefined\n    && dto.isTrashed !== true;\n}\nif (!partnersCompatible(dto)) { /* disable withPartners or clear filters */ }","typeGuard":null,"tryCatchPattern":"try { await timelineApi.buckets(dto); }\ncatch (e) {\n  if (e instanceof BadRequestException && /withPartners/.test(e.message)) {\n    // split into two requests: filters for self, withPartners for visible scope\n  }\n}","preventionTips":["UI: disable the 'show partners' toggle when any of archive/trash/favorite/locked is active.","Always set visibility explicitly (Visible) rather than leaving undefined when using partners."],"tags":["timeline","partners","validation","bad-request"],"backgroundTag":null,"analyzedSha":"199723261c6ffa897fec8ccdaea6359e39c37cc3","analyzedAt":"2026-08-12T04:54:27.085Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}