{"record":{"id":"2a103f6ad15489ba","repo":"toeverything/AFFiNE","slug":"content-too-large","errorCode":"CONTENT_TOO_LARGE","errorMessage":"Content too large","messagePattern":"Content too large","errorType":"exception","errorClass":"UserFriendlyError","httpStatus":413,"severity":"error","filePath":"packages/common/nbstore/src/impls/cloud/http.ts","lineNumber":54,"sourceCode":"          'x-affine-version': BUILD_CONFIG.appVersion,\n        },\n      })\n      .catch(err => {\n        throw new UserFriendlyError({\n          status: 504,\n          code: 'NETWORK_ERROR',\n          type: 'NETWORK_ERROR',\n          name: 'NETWORK_ERROR',\n          message: `Network error: ${err.message}`,\n          stacktrace: err.stack,\n        });\n      });\n    if (timeoutId) {\n      clearTimeout(timeoutId);\n    }\n    if (!res.ok && res.status !== 404) {\n      if (res.status === 413) {\n        throw new UserFriendlyError({\n          status: 413,\n          code: 'CONTENT_TOO_LARGE',\n          type: 'CONTENT_TOO_LARGE',\n          name: 'CONTENT_TOO_LARGE',\n          message: 'Content too large',\n        });\n      } else if (\n        res.headers.get('Content-Type')?.startsWith('application/json')\n      ) {\n        throw UserFriendlyError.fromAny(await res.json());\n      } else {\n        throw UserFriendlyError.fromAny(await res.text());\n      }\n    }\n    return res;\n  };\n\n  readonly fetchArrayBuffer = async (input: string, init?: RequestInit) => {","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/b4c8548c09da21b2898443559a5b846f0ccf5dd8/packages/common/nbstore/src/impls/cloud/http.ts#L36-L72","documentation":"HttpConnection.fetch maps any non-ok, non-404 response with status 413 to a UserFriendlyError with code/type/name CONTENT_TOO_LARGE and status 413. This is the generic HTTP layer signal that a request body exceeded a size limit somewhere on the server side — before app-level quota logic even sees it. Blob uploads wrap this further (see error 715), but any other 413 response from the API surfaces here directly.","triggerScenarios":"Any POST/PUT through connection.fetch or connection.gql whose body exceeds the server's or an intermediate proxy's body limit and the server answers 413; large GraphQL mutations/queries (e.g. batched operations, big base64 payloads).","commonSituations":"Sending large inline payloads (base64 images in mutations, huge doc updates) through the GraphQL endpoint behind nginx with default client_max_body_size; gateway/WAF body limits; inconsistent limits between environments (works locally, fails in prod).","solutions":["Reduce the request payload — move large binaries to the blob upload API instead of inlining them in GraphQL/JSON bodies.","On self-hosted: raise the reverse proxy body limit (nginx client_max_body_size, etc.) to match your real maximum payload.","Split batched mutations into smaller chunks.","Catch by code: err instanceof UserFriendlyError && err.code === 'CONTENT_TOO_LARGE'."],"exampleFix":"// before\nawait connection.gql({ query: updateDocMutation, variables: { content: base64Image } });\n\n// after\nconst { key } = await blobStorage.set({ key: nanoid(), data: bytes, mime });\nawait connection.gql({ query: updateDocMutation, variables: { content: `affine-blob:///${key}` } });","handlingStrategy":"validation","validationCode":"const MAX_BODY = 10 * 1024 * 1024; // keep in sync with proxy client_max_body_size\nfunction approxJsonSize(v: unknown): number { return new Blob([JSON.stringify(v)]).size; }\nif (approxJsonSize(variables) > MAX_BODY) throw new Error('payload too large — upload blobs separately');","typeGuard":"import { UserFriendlyError } from '@affine/error';\nconst isContentTooLarge = (e: unknown): e is UserFriendlyError =>\n  e instanceof UserFriendlyError && e.code === 'CONTENT_TOO_LARGE';","tryCatchPattern":"try { await connection.gql({ query, variables }); } catch (e) { if (isContentTooLarge(e)) { /* split the batch or move binaries to blob storage */ } throw e; }","preventionTips":["Never inline large base64/binary data in GraphQL variables","Chunk batched mutations","Align proxy client_max_body_size with the largest legitimate API payload"],"tags":["http","http-413","payload-limit","affine"],"backgroundTag":"http-413-request-entity-too-large","analyzedSha":"b4c8548c09da21b2898443559a5b846f0ccf5dd8","analyzedAt":"2026-08-18T21:16:52.546Z","contentChangedAt":"2026-08-18T21:16:52.546Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}