slymnoyann/hey-1 · error · Error

uploadFileToIPFS failed

Error message

uploadFileToIPFS failed

What it means

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.

Source

Thrown at src/helpers/accountPictureUtils.ts:30

    reader.readAsDataURL(file);
  });
};

const uploadCroppedImage = async (
  image: HTMLCanvasElement
): Promise<string> => {
  const blob = await new Promise((resolve) => image.toBlob(resolve));
  const file = new File([blob as Blob], "cropped_image.png", {
    type: (blob as Blob).type
  });
  const cleanedFile = await compressImage(file, {
    maxSizeMB: 6,
    maxWidthOrHeight: 3000
  });
  const attachment = await uploadFileToIPFS(cleanedFile);
  const decentralizedUrl = attachment.uri;
  if (!decentralizedUrl) {
    throw new Error("uploadFileToIPFS failed");
  }

  return decentralizedUrl;
};

export default uploadCroppedImage;

View on GitHub (pinned to 88c8f9d553)

Solutions

  1. Verify the IPFS upload environment configuration (endpoint URL, API key) in apps/web/.env against .env.example
  2. Reproduce with a tiny PNG to rule out size/timeout issues on large compressed images
  3. Log or inspect the raw response of uploadFileToIPFS to confirm the shape of the returned attachment object
  4. Add retry logic or user-facing error messaging around uploadCroppedImage so a transient IPFS failure is surfaced and retryable

Example fix

// before
const attachment = await uploadFileToIPFS(cleanedFile);
const decentralizedUrl = attachment.uri;
if (!decentralizedUrl) {
  throw new Error("uploadFileToIPFS failed");
}

// after
const attachment = await uploadFileToIPFS(cleanedFile);
const decentralizedUrl = attachment?.uri;
if (!decentralizedUrl) {
  console.error("IPFS upload returned no URI", attachment);
  throw new Error("uploadFileToIPFS failed");
}
Defensive patterns

Strategy: try-catch

Validate before calling

const MAX_BYTES = 6 * 1024 * 1024;
if (!(file instanceof File) || file.size === 0 || file.size > MAX_BYTES) {
  throw new Error("Invalid image file");
}

Type guard

const hasUri = (a: unknown): a is { uri: string } =>
  typeof a === "object" && a !== null && typeof (a as { uri?: unknown }).uri === "string" && (a as { uri: string }).uri.length > 0;

Try / catch

try {
  const url = await uploadCroppedImage(file);
} catch (e) {
  if (e instanceof Error && e.message === "uploadFileToIPFS failed") {
    // show retry UI, do not crash
  }
  throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of slymnoyann/hey-1@88c8f9d553 (2026-08-28). Data as JSON: /api/errors/75c23c0784afdfed. Report an issue: GitHub.