{"record":{"id":"76c6d1313daaea82","repo":"wavetermdev/waveterm","slug":"invalid-data-url","errorCode":null,"errorMessage":"Invalid data URL","messagePattern":"Invalid data URL","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"frontend/util/util.ts","lineNumber":452,"sourceCode":"                return \"\\\\f\";\n        }\n        if (code === 0x1b) return \"\\\\x1b\"; // escape\n        if (code < 0x20 || code === 0x7f) return `\\\\x${code.toString(16).padStart(2, \"0\")}`;\n        return ch;\n    });\n}\n\nfunction cn(...inputs: ClassValue[]) {\n    return twMerge(clsx(inputs));\n}\n\ntype ParsedDataUrl = {\n    mimeType: string;\n    buffer: Uint8Array;\n};\n\nfunction parseDataUrl(dataUrl: string): ParsedDataUrl {\n    if (!dataUrl.startsWith(\"data:\")) throw new Error(\"Invalid data URL\");\n    const [header, data] = dataUrl.split(\",\", 2);\n    if (data === undefined) throw new Error(\"Invalid data URL: missing data\");\n\n    const meta = header.slice(5);\n    let mimeType = \"text/plain;charset=US-ASCII\";\n    const parts = meta.split(\";\");\n    if (parts[0]) mimeType = parts[0];\n    const isBase64 = parts.some((p) => p.toLowerCase() === \"base64\");\n\n    let buffer: Uint8Array;\n    if (isBase64) {\n        buffer = base64ToArray(data);\n    } else {\n        // assume text\n        const decoded = decodeURIComponent(data);\n        buffer = new TextEncoder().encode(decoded);\n    }\n","sourceCodeStart":434,"sourceCodeEnd":470,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/frontend/util/util.ts#L434-L470","documentation":"parseDataUrl parses data: URLs into a mime type and byte buffer. It strictly requires the string to begin with the \"data:\" scheme; anything else is rejected with this error because it cannot be interpreted as a data URL.","triggerScenarios":"Calling parseDataUrl (via the parsed helper) with a plain http(s) URL, a bare base64 string, an empty string, or a data URL that lost its scheme after trimming/splitting.","commonSituations":"Storing only the base64 payload in a config and forgetting the \"data:\" prefix, copying an <img src> that was a normal URL, or string processing that stripped the prefix.","solutions":["Inspect the input string; confirm it starts with \"data:\".","If you only have raw base64, wrap it: `data:${mimeType};base64,${raw}`.","Skip the call for non-data URLs (check startsWith) and handle them through a different path.","Verify the source of the string (upload, clipboard, config) is producing a full data URL."],"exampleFix":"// before\nconst parsedUrl = parsed(imageSrc); // imageSrc = \"iVBORw0KGgo...\"\n// after\nconst dataUrl = imageSrc.startsWith(\"data:\") ? imageSrc : `data:image/png;base64,${imageSrc}`;\nconst parsedUrl = parsed(dataUrl);","handlingStrategy":"type-guard","validationCode":"if (typeof input === \"string\" && input.startsWith(\"data:\")) {\n  const result = parsed(input);\n} else {\n  // treat as regular URL or raw base64, route accordingly\n}","typeGuard":"function isDataUrl(s: unknown): s is string {\n  return typeof s === \"string\" && s.startsWith(\"data:\");\n}","tryCatchPattern":"try {\n  return parsed(dataUrl);\n} catch (e) {\n  if (String(e.message).startsWith(\"Invalid data URL\")) {\n    console.warn(\"not a data URL:\", dataUrl.slice(0, 32));\n    return null;\n  }\n  throw e;\n}","preventionTips":["Always check startsWith(\"data:\") before parsing image/src strings that could be plain URLs.","When persisting images, store the full data URL, not just the base64 payload.","Normalize inputs (trim, add scheme) at ingestion boundaries."],"tags":["data-url","parsing","invalid-argument"],"backgroundTag":"invalid-data-url","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}