wavetermdev/waveterm · error

error waiting for vdom context route: %v

Error message

error waiting for vdom context route: %v

What it means

CreateVDomContext registers a vdom context for the block and then waits for Wave's frontend to open the corresponding block route, using WaitForRouteCommand with a 4000ms wait and 5000ms RPC timeout. This error wraps a failure of that wait call itself — RPC timeout, transport error, or command rejection — meaning the client could not even complete the wait operation against the frontend route.

Source

Thrown at pkg/waveapp/waveapp.go:215

}

func (c *Client) CreateVDomContext(target *vdom.VDomTarget) error {
	blockORef, err := wshclient.VDomCreateContextCommand(
		c.RpcClient,
		vdom.VDomCreateContext{Target: target},
		&wshrpc.RpcOpts{Route: wshutil.MakeFeBlockRouteId(c.RpcContext.BlockId)},
	)
	if err != nil {
		return err
	}
	c.VDomContextBlockId = blockORef.OID
	log.Printf("created vdom context: %v\n", blockORef)
	gotRoute, err := wshclient.WaitForRouteCommand(c.RpcClient, wshrpc.CommandWaitForRouteData{
		RouteId: wshutil.MakeFeBlockRouteId(blockORef.OID),
		WaitMs:  4000,
	}, &wshrpc.RpcOpts{Timeout: 5000})
	if err != nil {
		return fmt.Errorf("error waiting for vdom context route: %v", err)
	}
	if !gotRoute {
		return fmt.Errorf("vdom context route could not be established")
	}
	wshclient.EventSubCommand(c.RpcClient, wps.SubscriptionRequest{Event: wps.Event_BlockClose, Scopes: []string{
		blockORef.String(),
	}}, nil)
	c.RpcClient.EventListener.On("blockclose", func(event *wps.WaveEvent) {
		c.doShutdown("got blockclose event")
	})
	return nil
}

func (c *Client) SendAsyncInitiation() error {
	if c.VDomContextBlockId == "" {
		return fmt.Errorf("no vdom context block id")
	}
	if c.GetIsDone() {

View on GitHub (pinned to a4447c1563)

Solutions

  1. Ensure the Wave window is open and the block is visible/rendering.
  2. Retry; transient frontend slowness can exceed the 5s timeout.
  3. Verify the blockORef OID matches a live block (not closed or from an old session).
  4. Increase the RpcOpts.Timeout if running on a heavily loaded machine.
  5. Check Wave logs for frontend errors creating the vdom context route.

Example fix

// before
gotRoute, err := wshclient.WaitForRouteCommand(c.RpcClient, wshrpc.CommandWaitForRouteData{RouteId: ..., WaitMs: 4000}, &wshrpc.RpcOpts{Timeout: 5000})
// after: longer timeout for slow frontends
gotRoute, err := wshclient.WaitForRouteCommand(c.RpcClient, wshrpc.CommandWaitForRouteData{RouteId: ..., WaitMs: 10000}, &wshrpc.RpcOpts{Timeout: 12000})
Defensive patterns

Strategy: try-catch

Validate before calling

if blockORef.OID == "" {
    return fmt.Errorf("cannot wait for vdom route: empty block OID")
}
// ensure the Wave window/block is open and rendering before waiting

Try / catch

gotRoute, err := wshclient.WaitForRouteCommand(c.RpcClient, wshrpc.CommandWaitForRouteData{
    RouteId: wshutil.MakeFeBlockRouteId(blockORef.OID),
    WaitMs:  4000,
}, &wshrpc.RpcOpts{Timeout: 5000})
if err != nil {
    return fmt.Errorf("error waiting for vdom context route: %v", err)
}
if !gotRoute {
    return fmt.Errorf("vdom context route could not be established")
}

Prevention

When it happens

Trigger: Calling CreateVDomContext when the Wave frontend is not rendering the block, the frontend process is busy/frozen so the 5000ms RpcOpts.Timeout expires, or the block OID in blockORef is invalid.

Common situations: Headless/minimized Wave where the frontend never spins up the block; slow machine exceeding the 5s timeout; block closed between creation and the wait; invalid OID from a stale block reference.

Related errors


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