CopilotKit/CopilotKit · error · Error

WhatsApp uploadMedia failed: ${res.status} ${await safeText(

Error message

WhatsApp uploadMedia failed: ${res.status} ${await safeText(res)}

What it means

Thrown when the WhatsApp Cloud API POST to /media returns a non-2xx status while uploading a file. The error message embeds the HTTP status code and the (truncated) response body via safeText, so the underlying cause (auth failure, unsupported media type, size limit) is visible in the message.

Source

Thrown at packages/channels-whatsapp/src/client.ts:122

      "file",
      new Blob(
        [
          (bytes.buffer as ArrayBuffer).slice(
            bytes.byteOffset,
            bytes.byteOffset + bytes.byteLength,
          ),
        ],
        { type: mimeType },
      ),
      filename,
    );
    const res = await this.fetchImpl(url, {
      method: "POST",
      headers: this.authHeader,
      body: form,
    });
    if (!res.ok)
      throw new Error(
        `WhatsApp uploadMedia failed: ${res.status} ${await safeText(res)}`,
      );
    const json = (await res.json()) as { id?: string };
    if (!json.id) throw new Error("WhatsApp uploadMedia returned no id");
    return json.id;
  }

  /** Resolve a media id to a download URL, then fetch the bytes. */
  async downloadMedia(mediaId: string): Promise<DownloadedMedia> {
    const metaUrl = `${this.base}/${this.apiVersion}/${mediaId}`;
    const metaRes = await this.fetchImpl(metaUrl, { headers: this.authHeader });
    if (!metaRes.ok)
      throw new Error(`WhatsApp media meta failed: ${metaRes.status}`);
    const meta = (await metaRes.json()) as { url?: string; mime_type?: string };
    if (!meta.url) throw new Error("WhatsApp media meta returned no url");
    const blobRes = await this.fetchImpl(meta.url, {
      headers: this.authHeader,
    });

View on GitHub (pinned to 68fbe97d87)

Solutions

  1. Check the status code and body in the message: 401/403 means refresh the access token; 415 means convert the file to a supported type (images jpeg/png, audio ogg/opus, video mp4, documents pdf etc.)
  2. Verify the phone number ID and API version used to build the client base URL
  3. Reduce media file size below WhatsApp's documented limits for its type
  4. Retry with backoff on 5xx/status 429 — transient Meta API errors

Example fix

// before
const id = await client.uploadMedia(bytes, "image/heic", "photo.heic");

// after
// convert unsupported format first
const id = await client.uploadMedia(bytes, "image/jpeg", "photo.jpg");
Defensive patterns

Strategy: try-catch

Validate before calling

const SUPPORTED = new Set(["image/jpeg","image/png","video/mp4","audio/ogg","application/pdf" /* etc */]);
if (!SUPPORTED.has(mimeType) || bytes.length > MAX_FOR_TYPE(mimeType)) throw new RangeError("unsupported media");

Type guard

function isUploadableMedia(m: {bytes: Uint8Array; mimeType: string}): boolean {
  return SUPPORTED_MIME.has(m.mimeType) && m.bytes.length > 0;
}

Try / catch

try { const id = await client.uploadMedia(...); } catch (e) { if (e instanceof Error && e.message.startsWith("WhatsApp uploadMedia failed")) { /* inspect status: 401 -> refresh token; 5xx/429 -> retry */ } throw e; }

Prevention

When it happens

Trigger: Calling uploadMedia()/mediaId() with an invalid/expired access token (401), a media file whose type is not supported by WhatsApp (415), a file exceeding WhatsApp's media size limits (413), or a malformed phone-number-id in the base URL (404).

Common situations: Expired WhatsApp access token (they expire after 24h), wrong phone number ID after switching WhatsApp Business accounts, uploading unsupported formats, or hitting the 100MB/16MB media limits depending on type.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of CopilotKit/CopilotKit@68fbe97d87 (2026-08-27). Data as JSON: /api/errors/453d7bf1ebc76bce. Report an issue: GitHub.