{"record":{"id":"1dfe7d301a9267d2","repo":"different-ai/openwork","slug":"openwork-could-not-decode-that-image","errorCode":null,"errorMessage":"OpenWork could not decode that image.","messagePattern":"OpenWork could not decode that image\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ee/apps/den-web/app/(den)/dashboard/_components/brand-appearance-screen.tsx","lineNumber":39,"sourceCode":"\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.\");\n  }\n\n  return { file, previewUrl: URL.createObjectURL(file), width, height };\n}\n\nfunction BrandAssetUploadField({","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/ee/apps/den-web/app/(den)/dashboard/_components/brand-appearance-screen.tsx#L21-L57","documentation":"After the type/size checks pass, the file is decoded with createImageBitmap; if decoding throws (corrupt data, truncated file, unsupported encoding inside the claimed type, or a browser without createImageBitmap support), the error is rethrown with this user-facing message.","triggerScenarios":"file.type says image/png or image/jpeg but the bytes are corrupt, truncated (partial download), actually another codec (mislabeled WebP/AVIF), or the browser lacks createImageBitmap (older Safari <15).","commonSituations":"Interrupted upload/download producing truncated files; files renamed to .png without conversion; progressive/CMYK JPEGs in odd decoders; old Safari where createImageBitmap is undefined so the call throws TypeError.","solutions":["Re-export or re-save the image in an editor to repair/normalize the file, then upload again.","Verify the file opens in a browser/image viewer; if not, the source file is corrupt.","Convert genuinely different codecs (WebP/AVIF renamed to .png) to real PNG/JPEG.","For old-Safari users, add a fallback decode path (Image + object URL) or a feature check for window.createImageBitmap."],"exampleFix":"// before\nimage = await createImageBitmap(file);\n// after\nif (typeof createImageBitmap === \"undefined\") {\n  image = await decodeViaImageElement(file); // fallback using new Image() + URL.createObjectURL\n} else {\n  image = await createImageBitmap(file);\n}","handlingStrategy":"try-catch","validationCode":"const isDecodeSupported = typeof createImageBitmap === \"function\";\nif (!isDecodeSupported) { fallbackToImageElementDecode(file); }","typeGuard":null,"tryCatchPattern":"try {\n  const asset = await createBrandAssetDraft(file, kind);\n} catch (error) {\n  if (error instanceof Error && error.message.includes(\"decode\")) showToast(\"The image file appears corrupt; try re-exporting it.\");\n  else showToast(error instanceof Error ? error.message : \"Could not use that image.\");\n}","preventionTips":["Feature-detect createImageBitmap and fall back to an Image-based decoder for old Safari","Re-download or re-export files that fail to open locally before uploading","Convert mislabeled codecs (WebP/AVIF renamed .png) to true PNG/JPEG","Never hand-edit image bytes; always export from a trusted editor"],"tags":["image-decoding","file-validation","browser-compatibility"],"backgroundTag":"image-decode-failed","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}