{"record":{"id":"536049d9d4fa78e7","repo":"wavetermdev/waveterm","slug":"invalid-data-url-missing-data","errorCode":null,"errorMessage":"Invalid data URL: missing data","messagePattern":"Invalid data URL: missing data","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"frontend/util/util.ts","lineNumber":454,"sourceCode":"        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\n    return { mimeType, buffer };\n}","sourceCodeStart":436,"sourceCodeEnd":472,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/frontend/util/util.ts#L436-L472","documentation":"parseDataUrl splits the data URL on the first comma to separate the metadata header from the payload. If no comma exists there is no data portion, so the string is a malformed data URL and this error is thrown.","triggerScenarios":"Calling parseDataUrl with strings like \"data:image/png\" or \"data:\" — a scheme-correct but payload-less data URL with no \",<data>\" part.","commonSituations":"Truncating the data URL (e.g. slicing for logging and passing the prefix back), building data URLs manually and forgetting the comma, or template interpolation of an empty base64 variable without the comma/separator.","solutions":["Log/inspect dataUrl.length and content; confirm it contains a comma after the metadata header.","Fix the producer to emit the full \"data:<mime>[;base64],<payload>\" form.","If an empty payload is legitimate, encode it explicitly as \"data:<mime>;base64,\" (with trailing comma) or guard before calling.","Add a pre-check: `if (!dataUrl.includes(\",\")) handle-empty-case`."],"exampleFix":"// before\nconst parsedUrl = parsed(`data:${mime}`); // no comma, no payload\n// after\nconst parsedUrl = parsed(`data:${mime};base64,${btoa(payload)}`);","handlingStrategy":"validation","validationCode":"function isWellFormedDataUrl(s: string): boolean {\n  return s.startsWith(\"data:\") && s.includes(\",\");\n}\nif (!isWellFormedDataUrl(dataUrl)) {\n  throw new Error(\"data URL missing comma-separated payload: \" + dataUrl.slice(0, 40));\n}\nconst result = parsed(dataUrl);","typeGuard":"function isCompleteDataUrl(s: unknown): s is string {\n  return typeof s === \"string\" && s.startsWith(\"data:\") && s.includes(\",\");\n}","tryCatchPattern":"try {\n  return parsed(dataUrl);\n} catch (e) {\n  if (String(e.message).startsWith(\"Invalid data URL: missing data\")) {\n    console.error(\"truncated data URL, length:\", dataUrl.length);\n    return null;\n  }\n  throw e;\n}","preventionTips":["Never slice/round-trip truncated data URLs (e.g. from logs or previews).","Emit data URLs from a single helper that always includes the comma and payload.","Validate with a includes(\",\") check before parsing."],"tags":["data-url","parsing","malformed-input"],"backgroundTag":"invalid-data-url","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}