toeverything/AFFiNE · warning · CommentAttachmentQuotaExceeded
comment_attachment_quota_exceeded
comment_attachment_quota_exceeded
Error message
You have exceeded the comment attachment size quota.
What it means
Thrown by `uploadCommentAttachment` when the in-memory buffer exceeds the hard-coded 10 MiB ceiling (`buffer.length > 10 * 1024 * 1024`). This is an absolute per-file guard independent of any workspace quota and fires before the workspace quota calculator runs. Code is `comment_attachment_quota_exceeded` (category `quota_exceeded`).
Source
Thrown at packages/backend/server/src/core/comment/resolver.ts:362
description: 'Upload a comment attachment and return the access url',
})
async uploadCommentAttachment(
@CurrentUser() me: UserType,
@Args('workspaceId') workspaceId: string,
@Args('docId') docId: string,
@Args({ name: 'attachment', type: () => GraphQLUpload })
attachment: FileUpload
) {
await this.assertPermission(
me,
{ workspaceId, docId },
'Doc.Comments.Create'
);
const buffer = await readableToBuffer(attachment.createReadStream());
// max attachment size is 10MB
if (buffer.length > 10 * 1024 * 1024) {
throw new CommentAttachmentQuotaExceeded();
}
const checkExceeded =
await this.quota.getWorkspaceQuotaCalculator(workspaceId);
const result = checkExceeded(buffer.length);
if (result?.blobQuotaExceeded || result?.storageQuotaExceeded) {
throw new CommentAttachmentQuotaExceeded();
}
const key = randomUUID();
await this.commentAttachmentStorage.put(
workspaceId,
docId,
key,
attachment.filename ?? key,
buffer,
me.id
);View on GitHub (pinned to 26c515e050)
Solutions
- Pre-check `file.size <= 10 * 1024 * 1024` on the client before opening the upload stream and reject early with a UI message.
- Compress or transcode large media (resize images, transcode video) before upload.
- Truncate or chunk the attachment, or host large files out-of-band and link them.
- Surface the 10 MiB limit in the attachment picker so users self-filter.
Example fix
// before
await client.mutate({
mutation: UPLOAD_COMMENT_ATTACHMENT,
variables: { workspaceId, docId, attachment: { file } },
});
// after
const MAX = 10 * 1024 * 1024;
if (file.size > MAX) {
toast(`Attachment exceeds the 10 MiB limit (got ${(file.size / 1048576).toFixed(1)} MiB).`);
return;
}
await client.mutate({
mutation: UPLOAD_COMMENT_ATTACHMENT,
variables: { workspaceId, docId, attachment: { file } },
}); Defensive patterns
Strategy: validation
Validate before calling
// Hard client-side cap matching the server constant
const MAX_ATTACHMENT_BYTES = 10 * 1024 * 1024;
function withinAttachmentLimit(file: File): boolean {
return file.size > 0 && file.size <= MAX_ATTACHMENT_BYTES;
}
if (!withinAttachmentLimit(file)) {
toast(`Attachment must be between 1 byte and 10 MiB (got ${file.size} bytes).`);
return;
} Type guard
function isUploadableFile(value: unknown): value is File {
return value instanceof File && typeof value.size === 'number' && value.size > 0;
} Try / catch
try {
await mutateUploadAttachment(workspaceId, docId, file);
} catch (e) {
if (e?.graphQLErrors?.[0]?.extensions?.code === 'comment_attachment_quota_exceeded') {
toast('Attachment is too large (10 MiB max).');
return;
}
throw e;
} Prevention
- Pre-check `file.size <= 10 * 1024 * 1024` before opening the upload stream.
- Show the 10 MiB limit in the attachment picker.
- Compress images/transcode media before upload to stay well under the cap.
When it happens
Trigger: Uploading any single attachment larger than 10 MiB through the `uploadCommentAttachment` mutation; streaming a large file whose realized buffer length crosses 10 MiB even if the client低估ed the size.
Common situations: Users dragging in large screenshots/PDFs/videos; clients that don't pre-check file size; uploads from mobile cameras producing multi-MB images.
Related errors
AI-assisted analysis of toeverything/AFFiNE@26c515e050 (2026-08-12).
Data as JSON: /api/errors/7b01f6b46736511d.
Report an issue: GitHub.