wavetermdev/waveterm · error
RPC error: %v
Error message
RPC error: %v
What it means
After proxying the HTTP request over the wsh RPC to the target process, handleVDom streams responses; if any response union carries an Error, pkg/web/webvdomproto.go:82 returns HTTP 500 with 'RPC error: <err>'. It means the remote VDom handler (in the block's process, routed via MakeProcRouteId(uuid)) failed or the RPC could not be delivered.
Source
Thrown at pkg/web/webvdomproto.go:82
URL: path,
Headers: headers,
Body: body,
}
// Get RPC client
client := wshserver.GetMainRpcClient()
// Make RPC call with route to specific process
route := wshutil.MakeProcRouteId(uuid)
respCh := wshclient.VDomUrlRequestCommand(client, data, &wshrpc.RpcOpts{
Route: route,
})
// Handle first response to set headers
firstResp := true
for respUnion := range respCh {
if respUnion.Error != nil {
http.Error(w, fmt.Sprintf("RPC error: %v", respUnion.Error), http.StatusInternalServerError)
return
}
resp := respUnion.Response
if firstResp {
firstResp = false
// Set status code and headers from first response
if resp.StatusCode > 0 {
w.WriteHeader(resp.StatusCode)
} else {
w.WriteHeader(http.StatusOK)
}
// Copy headers
for key, value := range resp.Headers {
w.Header().Set(key, value)
}
}
View on GitHub (pinned to a4447c1563)
Solutions
- Read the wrapped RPC error in the response body — 'route not found'/timeout means the target process is gone.
- Verify the block (UUID) still exists and is running; reopen the block and use its current UUID.
- Confirm the Wave app / target process is running and the main RPC client is connected.
- Retry after the remote process restarts; the route is re-registered when the block is recreated.
Example fix
// before: stale cached block id
await fetch(`/vdom/${cachedBlockId}/state`)
// after: refresh the live block id first
const liveId = await getActiveBlockId()
await fetch(`/vdom/${liveId}/state`) Defensive patterns
Strategy: validation
Validate before calling
// ensure the target block/process is live before proxying
const live = await isBlockActive(uuid); // via app state / block registry
if (!live) throw new Error(`vdom target ${uuid} is not running`); Type guard
function isVdomResp(u) {
return u != null && ("Response" in u || "Error" in u);
} Try / catch
const resp = await fetch(`/vdom/${uuid}/render`);
if (resp.status === 500) {
const msg = await resp.text();
if (msg.includes("RPC error")) {
// target process likely gone: refresh block id and retry once
return retryWithFreshBlockId();
}
throw new Error(msg);
} Prevention
- Resolve the current live block UUID at request time instead of caching it.
- Handle route-not-found/timeouts as 'target process closed' and refresh the id.
- Keep the Wave app/process running before issuing vdom proxy requests.
When it happens
Trigger: The target UUID does not correspond to a live block/process (no subscriber on the route), the remote VDomUrlRequest handler returns an error, or the RPC channel closes with an error (timeout, connection to the wave process lost).
Common situations: Hitting /vdom/ with a UUID for a block that was closed or crashed, the Wave terminal app not running so the main RPC client has no route, stale bookmarked vdom URLs pointing at dead blocks.
Related errors
- no default route
- wcloud endpoint not set
- wcloud ping endpoint not set
- nil wshrpc passed to wshclient
- response channel closed
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/3888f3704173cab6.
Report an issue: GitHub.