toeverything/AFFiNE · error · BlobQuotaExceeded

blob_quota_exceeded

blob_quota_exceeded

Error message

You have exceeded your blob size quota.

What it means

The resolver reads the request's content-length header and throws BlobQuotaExceeded (code blob_quota_exceeded) when it is >= MAX_EMBEDDABLE_SIZE (50 MB, defined in packages/backend/server/src/plugins/copilot/utils.ts). This is the per-artifact embedding size cap for the copilot workspace.

Source

Thrown at packages/backend/server/src/plugins/copilot/workspace/resolver.ts:180

  ): Promise<CopilotWorkspaceArtifactType> {
    await this.ac
      .user(user.id)
      .workspace(workspaceId)
      .assert('Workspace.Settings.Update');

    if (!this.copilotWorkspace.canEmbedding) {
      throw new CopilotEmbeddingUnavailable();
    }

    const lockFlag = `${COPILOT_LOCKER}:workspace:${workspaceId}`;
    await using lock = await this.mutex.acquire(lockFlag);
    if (!lock) {
      throw new TooManyRequest('Server is busy');
    }

    const length = Number(ctx.req.headers['content-length']);
    if (length && length >= MAX_EMBEDDABLE_SIZE) {
      throw new BlobQuotaExceeded();
    }

    try {
      return await this.copilotWorkspace.addArtifact(workspaceId, content);
    } catch (e) {
      // passthrough user friendly error
      if (e instanceof UserFriendlyError) {
        throw e;
      }
      throw new CopilotFailedToAddWorkspaceArtifact({
        message: e instanceof Error ? e.message : String(e),
      });
    }
  }

  @Mutation(() => Boolean, {
    name: 'removeWorkspaceArtifact',
    complexity: 2,

View on GitHub (pinned to b4c8548c09)

Solutions

  1. Reduce the artifact below 50 MB or split it into meaningful parts (extract text, compress media)
  2. Compress or transcode the file before upload
  3. If you self-host and genuinely need bigger docs, raise MAX_EMBEDDABLE_SIZE and matching body-size limits in your deployment - but mind the embedding provider's token limits

Example fix

// before
await mutate({ workspaceId, blob: file }); // 80MB pdf -> error

// after
if (file.size >= 50 * 1024 * 1024) throw new Error('artifact too large');
await mutate({ workspaceId, blob: await shrink(file) });
Defensive patterns

Strategy: validation

Validate before calling

const MAX_EMBEDDABLE_SIZE = 50 * 1024 * 1024;
if (file.size >= MAX_EMBEDDABLE_SIZE) {
  throw new RangeError(`artifact is ${file.size} bytes; cap is ${MAX_EMBEDDABLE_SIZE}`);
}
await mutate({ workspaceId, blob: file });

Type guard

const isEmbeddableSize = (f: File): boolean =>
  f.size < 50 * 1024 * 1024;

Try / catch

try {
  await mutate({ workspaceId, blob: file });
} catch (e) {
  if (e?.code === 'blob_quota_exceeded') {
    file = await compressOrSplit(file); // then retry once
    return mutate({ workspaceId, blob: file });
  }
  throw e;
}

Prevention

When it happens

Trigger: Uploading an artifact whose declared content-length is 50 MB or more: large PDFs, audio recordings, or dumps passed directly to addWorkspaceArtifact.

Common situations: Documents that exceed the cap because they embed images; proxies that strip the content-length header (this check is skipped, and oversized bodies then fail later during processing); callers assuming no size limit because GraphQL accepts any upload.

Understand the failure class

Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.

Related errors


AI-assisted analysis of toeverything/AFFiNE@b4c8548c09 (2026-08-18). Data as JSON: /api/errors/489edf09b77d1043. Report an issue: GitHub.