wavetermdev/waveterm · warning
Invalid UUID format
Error message
Invalid UUID format
What it means
handleVDom validates that the first path segment after /vdom/ is exactly 36 characters (a UUID). If not, pkg/web/webvdomproto.go:31 returns HTTP 400 'Invalid UUID format'. This is a length-only check, so any 36-char token passes even if not a real UUID.
Source
Thrown at pkg/web/webvdomproto.go:31
"github.com/wavetermdev/waveterm/pkg/wshrpc"
"github.com/wavetermdev/waveterm/pkg/wshrpc/wshclient"
"github.com/wavetermdev/waveterm/pkg/wshrpc/wshserver"
"github.com/wavetermdev/waveterm/pkg/wshutil"
)
// Add the new handler function
func handleVDom(w http.ResponseWriter, r *http.Request) {
// Extract UUID and path from URL
pathParts := strings.Split(strings.TrimPrefix(r.URL.Path, "/vdom/"), "/")
if len(pathParts) < 1 {
http.Error(w, "Invalid VDOM URL format", http.StatusBadRequest)
return
}
uuid := pathParts[0]
// Simple UUID validation
if len(uuid) != 36 {
http.Error(w, "Invalid UUID format", http.StatusBadRequest)
return
}
// Reconstruct the remaining path
path := "/" + strings.Join(pathParts[1:], "/")
if r.URL.RawQuery != "" {
path += "?" + r.URL.RawQuery
}
// Read request body if present
var body []byte
var err error
if r.Body != nil {
body, err = io.ReadAll(r.Body)
if err != nil {
http.Error(w, fmt.Sprintf("Error reading request body: %v", err), http.StatusInternalServerError)
return
}View on GitHub (pinned to a4447c1563)
Solutions
- Print/log the URL path on the client before the request and confirm the first segment after /vdom/ is exactly 36 characters.
- Obtain the correct UUID from the source of truth (block metadata / block controller) rather than a user-supplied or derived string.
- Trim whitespace and strip any surrounding brackets or quotes from the id before building the URL.
- If you control ids, generate them with a UUID v4 library so they are always 36 chars.
Example fix
// before
const url = `/vdom/${shortId}/render`
// after
if (blockId.length !== 36) throw new Error(`bad vdom id: ${blockId}`)
const url = `/vdom/${encodeURIComponent(blockId)}/render` Defensive patterns
Strategy: validation
Validate before calling
if (typeof blockId !== "string" || blockId.length !== 36) {
throw new Error(`invalid vdom uuid: ${blockId}`);
}
const resp = await fetch(`/vdom/${blockId}/${path}`); Type guard
function isVdomUuid(id) {
return typeof id === "string" && id.length === 36;
} Try / catch
if (!isVdomUuid(blockId)) throw new Error("invalid uuid before request");
const resp = await fetch(`/vdom/${blockId}/render`);
if (resp.status === 400) throw new Error(await resp.text()); Prevention
- Validate id length (36 chars) client-side before building /vdom/ URLs.
- Take block ids from the block registry, not from user input or truncated logs.
- Trim whitespace and strip brackets from ids copied from UI/log output.
When it happens
Trigger: Calling the /vdom/ endpoint with a block/route id whose first path segment is not 36 characters — empty id, truncated id, numeric id, or an id with surrounding whitespace.
Common situations: Passing a Wave block ID variant instead of the full UUID, a partially-constructed URL like /vdom//render (empty first segment), copy-pasting an id that was trimmed or truncated by logs, or using a pre-UUID identifier from an older version.
Related errors
- no content available
- failed to parse JSON: %v
- wcloud endpoint not set
- wcloud ping endpoint not set
- invalid AIMessage: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/be5fd5441dcbdc88.
Report an issue: GitHub.