{"record":{"id":"26a53c6a6ae7e951","repo":"immich-app/immich","slug":"asset-not-found","errorCode":null,"errorMessage":"Asset not found","messagePattern":"Asset not found","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"server/src/services/asset.service.ts","lineNumber":80,"sourceCode":"\n    const stats = await this.assetRepository.getStatistics(auth.user.id, dto);\n    return mapStats(stats);\n  }\n\n  async get(auth: AuthDto, id: string): Promise<AssetResponseDto | SanitizedAssetResponseDto> {\n    await this.requireAccess({ auth, permission: Permission.AssetRead, ids: [id] });\n\n    const asset = await this.assetRepository.getById(id, {\n      exifInfo: true,\n      owner: true,\n      faces: { person: true, viewingUserId: auth.user.id },\n      stack: { assets: true },\n      edits: true,\n      tags: true,\n    });\n\n    if (!asset) {\n      throw new BadRequestException('Asset not found');\n    }\n\n    if (auth.sharedLink && !auth.sharedLink.showExif) {\n      return mapAsset(asset, { stripMetadata: true, withStack: true, auth });\n    }\n\n    const data = mapAsset(asset, { withStack: true, auth });\n\n    if (auth.sharedLink) {\n      delete data.owner;\n    }\n\n    if (auth.sharedLink) {\n      data.people = [];\n    }\n\n    return data;\n  }","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/immich-app/immich/blob/e55ac299a4ec7cb372e35dbf2c6c05ee9ce77f6c/server/src/services/asset.service.ts#L62-L98","documentation":"assetService.get loads an asset with relations (stack, edits, tags, etc.) and throws BadRequestException('Asset not found') when the repository returns null. It is called by update (which returns this.get) as well as directly, so both read and update flows surface this message. Note it is a 400, not a 404, despite being a missing-resource error.","triggerScenarios":"PUT /api/assets/:id (update) or the internal get() call with an id that does not exist, was deleted, or belongs to another user/album not visible via the auth context (e.g. shared link without access).","commonSituations":"Stale client caches holding ids of deleted assets; copying ids between Immich instances; shared-link users attempting operations on assets outside the link; races with trash emptying.","solutions":["Verify the asset exists and is accessible: GET /api/assets/:id with the same credentials.","Refresh the client's asset list to drop deleted/stale ids.","For shared-link flows, ensure the asset is part of the shared link's album.","If you own the id generation, validate the UUID before calling (a truncated id never matches)."],"exampleFix":"// before\nawait api.updateAsset(id, { description: 'x' }); // stale id\n// after\nconst exists = await api.getAssetInfo(id).catch(() => null);\nif (exists) await api.updateAsset(id, { description: 'x' });\nelse await refreshAssetList();","handlingStrategy":"try-catch","validationCode":"const asset = await api.getAssetInfo(id).catch(() => null);\nif (!asset) throw new Error(`Asset ${id} missing or inaccessible`);","typeGuard":null,"tryCatchPattern":"try { await api.updateAsset(id, dto); } catch (e) { if (String(e).includes('Asset not found')) { removeFromCache(id); return; } throw e; }","preventionTips":["Re-fetch asset lists after deletes to purge stale ids","Validate UUID format before calling","For shared links, only reference assets inside the shared album"],"tags":["not-found","asset","bad-request","stale-id"],"backgroundTag":"entity-not-found","analyzedSha":"e55ac299a4ec7cb372e35dbf2c6c05ee9ce77f6c","analyzedAt":"2026-09-15T07:20:19.675Z","contentChangedAt":"2026-09-15T07:20:19.675Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}