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
- 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.)
- Verify the phone number ID and API version used to build the client base URL
- Reduce media file size below WhatsApp's documented limits for its type
- 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
- Validate mime type and size before uploading
- Keep the access token fresh (fetch shortly before use)
- Wrap uploads in retry-with-backoff for 429/5xx
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
- WhatsApp uploadMedia returned no id
- WhatsApp media meta failed: ${metaRes.status}
- WhatsApp media download failed: ${blobRes.status}
- WhatsApp media meta returned no url
- WhatsApp control value too large to round-trip: encoded id i
AI-assisted analysis of CopilotKit/CopilotKit@68fbe97d87 (2026-08-27).
Data as JSON: /api/errors/453d7bf1ebc76bce.
Report an issue: GitHub.