{"record":{"id":"76c76f40d48728fa","repo":"toeverything/AFFiNE","slug":"storage-quota-exceeded","errorCode":"storage_quota_exceeded","errorMessage":"You have exceeded your storage quota.","messagePattern":"You have exceeded your storage quota\\.","errorType":"exception","errorClass":"StorageQuotaExceeded","httpStatus":402,"severity":"error","filePath":"packages/backend/server/src/core/workspaces/resolvers/blob.ts","lineNumber":190,"sourceCode":"  async setBlob(\n    @CurrentUser() user: CurrentUser,\n    @Args('workspaceId') workspaceId: string,\n    @Args({ name: 'blob', type: () => GraphQLUpload })\n    blob: FileUpload\n  ) {\n    await this.ac\n      .user(user.id)\n      .workspace(workspaceId)\n      .assert('Workspace.Blobs.Write');\n\n    const checkExceeded =\n      await this.quota.getWorkspaceQuotaCalculator(workspaceId);\n\n    let result = checkExceeded(0);\n    if (result?.blobQuotaExceeded) {\n      throw new BlobQuotaExceeded();\n    } else if (result?.storageQuotaExceeded) {\n      throw new StorageQuotaExceeded();\n    }\n\n    const buffer = await readBuffer(blob.createReadStream(), checkExceeded);\n\n    await this.storage.put(workspaceId, blob.filename, buffer);\n    return blob.filename;\n  }\n\n  @Mutation(() => BlobUploadInit)\n  async createBlobUpload(\n    @CurrentUser() user: CurrentUser,\n    @Args('workspaceId') workspaceId: string,\n    @Args('key') key: string,\n    @Args('size', { type: () => Int }) size: number,\n    @Args('mime') mime: string\n  ): Promise<BlobUploadInit> {\n    await this.ac\n      .user(user.id)","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/26c515e050211269e911f7d9cfe162a26c83ed98/packages/backend/server/src/core/workspaces/resolvers/blob.ts#L172-L208","documentation":"Sibling of 313: thrown when checkExceeded(0) reports storageQuotaExceeded. The workspace's total storage usage already exceeds the plan's storage quota, so the blob upload is refused before any bytes are read.","triggerScenarios":"The setBlob mutation when the workspace is already over its total storage quota (calculator at size 0).","commonSituations":"Plan downgrade; large doc/blob accumulation; stale usage metrics; multi-tenant shared storage limits.","solutions":["Reduce storage usage (blobs, docs, history) below quota.","Upgrade the plan's storage quota.","Ensure usage metrics feeding the calculator are up to date.","Surface storage usage in the UI."],"exampleFix":"// before\nawait storage.put(ws, file.name, buf)\n// after\nconst calc = await quota.getWorkspaceQuotaCalculator(ws)\nif (calc(0)?.storageQuotaExceeded) return promptStorageUpgrade()","handlingStrategy":"validation","validationCode":"const calc = await quota.getWorkspaceQuotaCalculator(workspaceId)\nif (calc(0)?.storageQuotaExceeded) return promptStorageUpgrade()","typeGuard":null,"tryCatchPattern":"try { await uploadBlob(file) } catch (e) {\n  if (e.code === 'storage_quota_exceeded') promptStorageUpgrade()\n  else throw e\n}","preventionTips":["Track total storage vs the plan cap.","Clean up old versions/history.","Alert before hitting the ceiling."],"tags":["quota","storage","limits","billing"],"backgroundTag":null,"analyzedSha":"26c515e050211269e911f7d9cfe162a26c83ed98","analyzedAt":"2026-08-12T13:15:16.447Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}