wavetermdev/waveterm · error

Unsupported or invalid image type: ${blob.type}

Error message

Unsupported or invalid image type: ${blob.type}

What it means

createTempFileFromBlob only supports MIME types present in the MIME_TO_EXT map; blobs that are not images or use an unmapped MIME type are rejected because no file extension can be derived for the temp file.

Source

Thrown at frontend/app/view/term/termutil.ts:89

/**
 * Creates a temporary file from a Blob (typically an image).
 * Validates size, generates a unique filename, saves to temp directory,
 * and returns the file path.
 *
 * @param blob - The Blob to save
 * @returns The path to the created temporary file
 * @throws Error if blob is too large (>5MB) or data URL is invalid
 */
export async function createTempFileFromBlob(blob: Blob): Promise<string> {
    // Check size limit (5MB)
    if (blob.size > 5 * 1024 * 1024) {
        throw new Error("Image too large (>5MB)");
    }

    // Get file extension from MIME type
    if (!blob.type.startsWith("image/") || !MIME_TO_EXT[blob.type]) {
        throw new Error(`Unsupported or invalid image type: ${blob.type}`);
    }
    const ext = MIME_TO_EXT[blob.type];

    // Generate unique filename with timestamp and random component
    const timestamp = Date.now();
    const random = Math.random().toString(36).substring(2, 8);
    const filename = `waveterm_paste_${timestamp}_${random}.${ext}`;

    const arrayBuffer = await new Promise<ArrayBuffer>((resolve, reject) => {
        const reader = new FileReader();
        reader.onload = () => resolve(reader.result as ArrayBuffer);
        reader.onerror = reject;
        reader.readAsArrayBuffer(blob);
    });

    const base64Data = base64.fromByteArray(new Uint8Array(arrayBuffer));

    // Write image to temp file and get path

View on GitHub (pinned to a4447c1563)

Solutions

  1. Convert the blob to a supported type (png/jpeg) before calling createTempFileFromBlob
  2. Add the missing MIME type to the MIME_TO_EXT map in termutil.ts
  3. Verify clipboard/drop handlers only pass image blobs through to this function

Example fix

// before
await createTempFileFromBlob(clipboardBlob);

// after
if (!clipboardBlob.type.startsWith("image/")) return;
const pngBlob = await ensurePng(clipboardBlob);
await createTempFileFromBlob(pngBlob);
Defensive patterns

Strategy: type-guard

Validate before calling

import { MIME_TO_EXT } from "./termutil";
const ok = blob instanceof Blob && blob.type.startsWith("image/") && MIME_TO_EXT[blob.type] != null;

Type guard

function hasKnownMime(blob: Blob): boolean {
    return blob.type.startsWith("image/") && MIME_TO_EXT[blob.type] != null;
}

Try / catch

try {
    const path = await createTempFileFromBlob(blob);
} catch (e) {
    if (String(e.message).startsWith("Unsupported or invalid image type")) {
        convertAndRetry(blob); // e.g. draw to canvas and export PNG
    } else { throw e; }
}

Prevention

When it happens

Trigger: Blob.type does not start with "image/", or starts with image/ but the exact MIME string (e.g. image/svg+xml, image/heic) has no entry in MIME_TO_EXT.

Common situations: Pasting non-image clipboard content (HTML, PDF); dropping SVG or HEIC images; browser normalizing a MIME type to a value the map lacks.

Related errors


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/a65b9f8fb5f061e2. Report an issue: GitHub.