{"record":{"id":"1ecac8514ed1fd44","repo":"different-ai/openwork","slug":"use-an-image-under-2-mb","errorCode":null,"errorMessage":"Use an image under 2 MB.","messagePattern":"Use an image under 2 MB\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"ee/apps/den-web/app/(den)/dashboard/_components/brand-appearance-screen.tsx","lineNumber":33,"sourceCode":"import { DenInput } from \"../../_components/ui/input\";\nimport { DenNotice } from \"../../_components/ui/notice\";\nimport { useOrgDashboard } from \"../_providers/org-dashboard-provider\";\nimport { EnterprisePlanNotice } from \"./enterprise-plan-notice\";\n\nconst BRAND_ASSET_MAX_BYTES = 2 * 1024 * 1024;\n\ntype BrandAssetKind = \"logo\" | \"icon\";\n\ntype BrandAssetDraft = {\n  file: File;\n  previewUrl: string;\n  width: number;\n  height: number;\n};\n\nasync function createBrandAssetDraft(file: File, kind: BrandAssetKind): Promise<BrandAssetDraft> {\n  if (file.type !== \"image/png\" && file.type !== \"image/jpeg\") throw new Error(\"Use a PNG or JPEG image.\");\n  if (file.size > BRAND_ASSET_MAX_BYTES) throw new Error(\"Use an image under 2 MB.\");\n\n  let image: ImageBitmap;\n  try {\n    image = await createImageBitmap(file);\n  } catch {\n    throw new Error(\"OpenWork could not decode that image.\");\n  }\n\n  const { width, height } = image;\n  image.close();\n  if (width > 4096 || height > 4096) throw new Error(\"Use an image no larger than 4096×4096 pixels.\");\n  if (kind === \"icon\") {\n    if (width < 64 || height < 64) throw new Error(\"Use a square icon at least 64×64 pixels.\");\n    if (width !== height) throw new Error(\"Use a square image for the app icon.\");\n  } else {\n    const aspectRatio = width / height;\n    if (width < 128 || height < 32) throw new Error(\"Use a wordmark at least 128×32 pixels.\");\n    if (aspectRatio < 1.5 || aspectRatio > 8) throw new Error(\"Use a horizontal wordmark between 1.5:1 and 8:1.\");","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/ee/apps/den-web/app/(den)/dashboard/_components/brand-appearance-screen.tsx#L15-L51","documentation":"BRAND_ASSET_MAX_BYTES is 2 MB; createBrandAssetDraft rejects any file above this limit before decoding. The limit keeps uploads small, avoids memory pressure in createImageBitmap, and bounds storage in Den.","triggerScenarios":"Uploading a PNG/JPEG icon or wordmark whose file.size exceeds 2 MB — e.g. a 4K-resolution logo export, a JPEG at maximum quality, or a PNG with photographic content.","commonSituations":"Exporting straight from design tools at full resolution (Figma 2x/3x exports of large frames); screenshots pasted as PNG; photos used as banners without compression.","solutions":["Resize the image so it fits within the required dimensions (icon: square ≥64×64; wordmark: ≥128×32, ≤4096×4096) then re-export.","Export as JPEG at quality ~80 for photographic wordmarks, or use PNG compression (tinypng, squoosh) for icons.","Reduce color depth / remove alpha if PNG is bloated by photographic content — switch to JPEG.","Check file size before upload (file.size < 2 * 1024 * 1024) so the error never surfaces."],"exampleFix":"// before\nconst file = exportFromFigma({ scale: 4 }); // ~6 MB PNG\n// after\nconst file = exportFromFigma({ scale: 1, format: \"png\", compress: true }); // < 2 MB","handlingStrategy":"validation","validationCode":"const BRAND_ASSET_MAX_BYTES = 2 * 1024 * 1024;\nif (file.size > BRAND_ASSET_MAX_BYTES) { alert(\"Please use an image under 2 MB.\"); return; }","typeGuard":null,"tryCatchPattern":"try {\n  const asset = await createBrandAssetDraft(file, kind);\n} catch (error) {\n  showToast(error instanceof Error ? error.message : \"Could not use that image.\");\n}","preventionTips":["Show the 2 MB limit in the upload UI before the user selects a file","Pre-compress images client-side (canvas export at 0.8 quality) when over the limit","Use PNG compressors (squoosh/tinypng) in the design export pipeline","Check file.size before invoking the uploader"],"tags":["file-validation","image","file-size"],"backgroundTag":"file-too-large","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}