wavetermdev/waveterm · error

invalid context, must have a routeid

Error message

invalid context, must have a routeid

What it means

This error comes from validateRpcContextFromAuth, which normalizes an RpcContext after authentication. A non-router context must carry either a RouteId or a ProcRoute marker so the wsh router knows where to send RPCs; otherwise it is unaddressable. The library throws it to prevent routing RPCs to an unknown destination.

Source

Thrown at pkg/wshutil/wshrouter_controlimpl.go:303

	log.Printf("wshrouter authenticate-jobmanager success linkid=%d jobid=%q routeid=%q", linkId, data.JobId, routeId)
	impl.Router.trustLink(linkId, LinkKind_Leaf)
	impl.Router.bindRoute(linkId, routeId, true)

	return nil
}

func validateRpcContextFromAuth(newCtx *wshrpc.RpcContext) (string, error) {
	if newCtx == nil {
		return "", fmt.Errorf("no context found in jwt token")
	}
	if newCtx.IsRouter && newCtx.RouteId != "" {
		return "", fmt.Errorf("invalid context, router cannot have a routeid")
	}
	if newCtx.IsRouter && newCtx.ProcRoute {
		return "", fmt.Errorf("invalid context, router cannot have a proc-route")
	}
	if !newCtx.IsRouter && newCtx.RouteId == "" && !newCtx.ProcRoute {
		return "", fmt.Errorf("invalid context, must have a routeid")
	}
	if newCtx.IsRouter {
		return "", nil
	}
	return newCtx.GenerateRouteId(), nil
}

View on GitHub (pinned to a4447c1563)

Solutions

  1. Set RouteId on the RpcContext before authentication (e.g. ctx.RouteId = connRouteId)
  2. If the context is a per-proc connection, set ProcRoute = true instead
  3. If this connection really is a router, set IsRouter = true (then RouteId must be empty)
  4. Verify the client handshake sends its routeid metadata (waveclient/wsh connect flags)

Example fix

// before
ctx := wshutil.RpcContext{} // no RouteId
// after
ctx := wshutil.RpcContext{RouteId: routeId}
Defensive patterns

Strategy: validation

Validate before calling

func validRpcContext(ctx wshutil.RpcContext) bool {
	return ctx.IsRouter || ctx.ProcRoute || ctx.RouteId != ""
}
if !validRpcContext(ctx) {
	ctx.RouteId = myRouteId // assign before authenticating
}

Type guard

func isAddressable(ctx wshutil.RpcContext) bool {
	return ctx.IsRouter || ctx.ProcRoute || ctx.RouteId != ""
}

Prevention

When it happens

Trigger: Calling AuthenticateCommand or extractTokenData with an auth/context whose IsRouter is false, ProcRoute is false, and RouteId is empty string.

Common situations: A client connects over a wsh pipe/route without setting routeid in its metadata; a manually constructed RpcContext missing RouteId; a server-side component forwarding auth for a connection that never registered a route; version mismatches where old clients omit routeid.

Related errors


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