{"record":{"id":"f746026fbda586bf","repo":"immich-app/immich","slug":"quota-has-been-exceeded","errorCode":null,"errorMessage":"Quota has been exceeded!","messagePattern":"Quota has been exceeded!","errorType":"http","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"server/src/services/asset-media.service.ts","lineNumber":370,"sourceCode":"    }\n\n    const album = await this.albumRepository.getById(sharedLink.albumId, { withAssets: false });\n    if (!album) {\n      return;\n    }\n\n    await this.albumRepository.addAssetIds(album.id, [assetId]);\n    const userIds = album.albumUsers.map(({ user }) => user.id);\n    await this.eventRepository.emit('AlbumUpdate', {\n      id: album.id,\n      userIds,\n      recipientIds: userIds,\n    });\n  }\n\n  private requireQuota(auth: AuthDto, size: number) {\n    if (auth.user.quotaSizeInBytes !== null && auth.user.quotaSizeInBytes < auth.user.quotaUsageInBytes + size) {\n      throw new BadRequestException('Quota has been exceeded!');\n    }\n  }\n}\n","sourceCodeStart":352,"sourceCodeEnd":374,"githubUrl":"https://github.com/immich-app/immich/blob/199723261c6ffa897fec8ccdaea6359e39c37cc3/server/src/services/asset-media.service.ts#L352-L374","documentation":"Thrown by AssetMediaService.requireQuota as BadRequestException (HTTP 400) when the authenticated user's quota would be exceeded by the upload: auth.user.quotaSizeInBytes is non-null and quotaUsageInBytes + file.size exceeds it. The check runs after the upload-access check but during uploadAsset, before the asset is committed.","triggerScenarios":"POST /assets (upload) where the incoming file size pushes the user's total stored bytes above their configured quotaSizeInBytes. Only fires when an admin has set a non-null quota for the user.","commonSituations":"User on a capped plan; admin sets quota after the user already approached the limit; bulk upload of large media that crosses the threshold mid-batch.","solutions":["Free up space by deleting existing assets to get below quota","Ask an admin to raise the user's quotaSizeInBytes (User management → quota)","Check current usage vs quota before starting a bulk upload and skip/throttle accordingly","Upload smaller files or compress media first"],"exampleFix":"// before\nfor (const f of files) await sdk.uploadAsset(f); // 400 on the one that tips over\n// after\nconst me = await sdk.getMyUser();\nconst remaining = me.quotaSizeInBytes - me.quotaUsageInBytes;\nconst fitting = files.filter(f => f.size <= remaining);","handlingStrategy":"validation","validationCode":"// Check remaining quota before uploading\nconst me = await sdk.getMyUser();\nif (me.quotaSizeInBytes != null) {\n  const remaining = me.quotaSizeInBytes - me.quotaUsageInBytes;\n  if (file.size > remaining) {\n    throw new Error(`Upload would exceed quota (need ${file.size}, have ${remaining})`);\n  }\n}\nawait sdk.uploadAsset(file);","typeGuard":"function hasQuota(u: { quotaSizeInBytes?: number | null }): u is { quotaSizeInBytes: number; quotaUsageInBytes: number } {\n  return typeof u.quotaSizeInBytes === 'number';\n}","tryCatchPattern":null,"preventionTips":["Fetch the user's quota and usage before starting a bulk upload; skip files that won't fit","Have admins raise the quota or delete unused assets when approaching the limit","Show remaining quota in the UI so users self-govern before upload"],"tags":["upload","quota","validation","nestjs","storage"],"backgroundTag":null,"analyzedSha":"199723261c6ffa897fec8ccdaea6359e39c37cc3","analyzedAt":"2026-08-12T04:54:27.085Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}