{"record":{"id":"a65b9f8fb5f061e2","repo":"wavetermdev/waveterm","slug":"unsupported-or-invalid-image-type-blob-type","errorCode":null,"errorMessage":"Unsupported or invalid image type: ${blob.type}","messagePattern":"Unsupported or invalid image type: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"frontend/app/view/term/termutil.ts","lineNumber":89,"sourceCode":"\n/**\n * Creates a temporary file from a Blob (typically an image).\n * Validates size, generates a unique filename, saves to temp directory,\n * and returns the file path.\n *\n * @param blob - The Blob to save\n * @returns The path to the created temporary file\n * @throws Error if blob is too large (>5MB) or data URL is invalid\n */\nexport async function createTempFileFromBlob(blob: Blob): Promise<string> {\n    // Check size limit (5MB)\n    if (blob.size > 5 * 1024 * 1024) {\n        throw new Error(\"Image too large (>5MB)\");\n    }\n\n    // Get file extension from MIME type\n    if (!blob.type.startsWith(\"image/\") || !MIME_TO_EXT[blob.type]) {\n        throw new Error(`Unsupported or invalid image type: ${blob.type}`);\n    }\n    const ext = MIME_TO_EXT[blob.type];\n\n    // Generate unique filename with timestamp and random component\n    const timestamp = Date.now();\n    const random = Math.random().toString(36).substring(2, 8);\n    const filename = `waveterm_paste_${timestamp}_${random}.${ext}`;\n\n    const arrayBuffer = await new Promise<ArrayBuffer>((resolve, reject) => {\n        const reader = new FileReader();\n        reader.onload = () => resolve(reader.result as ArrayBuffer);\n        reader.onerror = reject;\n        reader.readAsArrayBuffer(blob);\n    });\n\n    const base64Data = base64.fromByteArray(new Uint8Array(arrayBuffer));\n\n    // Write image to temp file and get path","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/frontend/app/view/term/termutil.ts#L71-L107","documentation":"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.","triggerScenarios":"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.","commonSituations":"Pasting non-image clipboard content (HTML, PDF); dropping SVG or HEIC images; browser normalizing a MIME type to a value the map lacks.","solutions":["Convert the blob to a supported type (png/jpeg) before calling createTempFileFromBlob","Add the missing MIME type to the MIME_TO_EXT map in termutil.ts","Verify clipboard/drop handlers only pass image blobs through to this function"],"exampleFix":"// before\nawait createTempFileFromBlob(clipboardBlob);\n\n// after\nif (!clipboardBlob.type.startsWith(\"image/\")) return;\nconst pngBlob = await ensurePng(clipboardBlob);\nawait createTempFileFromBlob(pngBlob);","handlingStrategy":"type-guard","validationCode":"import { MIME_TO_EXT } from \"./termutil\";\nconst ok = blob instanceof Blob && blob.type.startsWith(\"image/\") && MIME_TO_EXT[blob.type] != null;","typeGuard":"function hasKnownMime(blob: Blob): boolean {\n    return blob.type.startsWith(\"image/\") && MIME_TO_EXT[blob.type] != null;\n}","tryCatchPattern":"try {\n    const path = await createTempFileFromBlob(blob);\n} catch (e) {\n    if (String(e.message).startsWith(\"Unsupported or invalid image type\")) {\n        convertAndRetry(blob); // e.g. draw to canvas and export PNG\n    } else { throw e; }\n}","preventionTips":["Filter clipboard/drop events to image/* MIME types before handling","Normalize exotic types (svg, heic) to png/jpeg via canvas before use","Keep MIME_TO_EXT updated when adding supported formats"],"tags":["image","mime-type","validation"],"backgroundTag":"unsupported-file-type","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}