{"record":{"id":"75c23c0784afdfed","repo":"slymnoyann/hey-1","slug":"uploadfiletoipfs-failed","errorCode":null,"errorMessage":"uploadFileToIPFS failed","messagePattern":"uploadFileToIPFS failed","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/helpers/accountPictureUtils.ts","lineNumber":30,"sourceCode":"    reader.readAsDataURL(file);\n  });\n};\n\nconst uploadCroppedImage = async (\n  image: HTMLCanvasElement\n): Promise<string> => {\n  const blob = await new Promise((resolve) => image.toBlob(resolve));\n  const file = new File([blob as Blob], \"cropped_image.png\", {\n    type: (blob as Blob).type\n  });\n  const cleanedFile = await compressImage(file, {\n    maxSizeMB: 6,\n    maxWidthOrHeight: 3000\n  });\n  const attachment = await uploadFileToIPFS(cleanedFile);\n  const decentralizedUrl = attachment.uri;\n  if (!decentralizedUrl) {\n    throw new Error(\"uploadFileToIPFS failed\");\n  }\n\n  return decentralizedUrl;\n};\n\nexport default uploadCroppedImage;\n","sourceCodeStart":12,"sourceCodeEnd":37,"githubUrl":"https://github.com/slymnoyann/hey-1/blob/88c8f9d55340d57a37846ff72f55c2c604e3a566/src/helpers/accountPictureUtils.ts#L12-L37","documentation":"Thrown by uploadCroppedImage after a successful image compression when uploadFileToIPFS returns an attachment whose uri field is falsy. This means the IPFS upload call resolved but produced no usable content URI, so the cropped avatar cannot be pinned to decentralized storage. It is a wrapper guard around the lower-level uploadFileToIPFS helper.","triggerScenarios":"Calling uploadCroppedImage with a cropped image whose underlying POST to the IPFS upload endpoint returns an empty/malformed array, or a response object without a uri field. Also triggered when the upload API returns 200 with an empty body or a proxy strips the response.","commonSituations":"IPFS node/gateway outage, wrong or missing IPFS API credentials/env vars in the web app, network flakiness on large (up to 6MB / 3000px) images after compression, or a backend version change that renamed uri to something else (e.g. cid or url) in the upload response.","solutions":["Verify the IPFS upload environment configuration (endpoint URL, API key) in apps/web/.env against .env.example","Reproduce with a tiny PNG to rule out size/timeout issues on large compressed images","Log or inspect the raw response of uploadFileToIPFS to confirm the shape of the returned attachment object","Add retry logic or user-facing error messaging around uploadCroppedImage so a transient IPFS failure is surfaced and retryable"],"exampleFix":"// before\nconst attachment = await uploadFileToIPFS(cleanedFile);\nconst decentralizedUrl = attachment.uri;\nif (!decentralizedUrl) {\n  throw new Error(\"uploadFileToIPFS failed\");\n}\n\n// after\nconst attachment = await uploadFileToIPFS(cleanedFile);\nconst decentralizedUrl = attachment?.uri;\nif (!decentralizedUrl) {\n  console.error(\"IPFS upload returned no URI\", attachment);\n  throw new Error(\"uploadFileToIPFS failed\");\n}","handlingStrategy":"try-catch","validationCode":"const MAX_BYTES = 6 * 1024 * 1024;\nif (!(file instanceof File) || file.size === 0 || file.size > MAX_BYTES) {\n  throw new Error(\"Invalid image file\");\n}","typeGuard":"const hasUri = (a: unknown): a is { uri: string } =>\n  typeof a === \"object\" && a !== null && typeof (a as { uri?: unknown }).uri === \"string\" && (a as { uri: string }).uri.length > 0;","tryCatchPattern":"try {\n  const url = await uploadCroppedImage(file);\n} catch (e) {\n  if (e instanceof Error && e.message === \"uploadFileToIPFS failed\") {\n    // show retry UI, do not crash\n  }\n  throw e;\n}","preventionTips":["Validate file size/type before compression and upload","Check navigator.onLine before starting the upload","Retry once on transient IPFS failures before surfacing the error to the user"],"tags":["ipfs","upload","image","storage","validation"],"backgroundTag":"ipfs-upload-failed","analyzedSha":"88c8f9d55340d57a37846ff72f55c2c604e3a566","analyzedAt":"2026-08-28T16:20:43.640Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}