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

  1. Read the wrapped RPC error in the response body — 'route not found'/timeout means the target process is gone.
  2. Verify the block (UUID) still exists and is running; reopen the block and use its current UUID.
  3. Confirm the Wave app / target process is running and the main RPC client is connected.
  4. 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

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


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/3888f3704173cab6. Report an issue: GitHub.