wavetermdev/waveterm · error
invalid context, router cannot have a routeid
Error message
invalid context, router cannot have a routeid
What it means
Sentinel/creation-time validation: a router (as opposed to an RPC endpoint) context must not carry a route ID. This error is returned when building or validating a router context that unexpectedly has a route ID set, which would corrupt routing semantics.
Source
Thrown at pkg/wshutil/wshrouter_controlimpl.go:297
log.Printf("wshrouter authenticate-jobmanager error linkid=%d jobid=%q: failed to verify job auth token: %v", linkId, data.JobId, err)
return fmt.Errorf("failed to verify job auth token: %w", err)
}
}
routeId := MakeJobRouteId(data.JobId)
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
- Set RouteId to "" when IsRouter is true in the token's RpcContext
- Fix token-minting code to build the router context without a route id
- Use the correct context constructor for router vs leaf connections
Example fix
// before
ctx := wshrpc.RpcContext{IsRouter: true, RouteId: myRouteId}
// after
ctx := wshrpc.RpcContext{IsRouter: true, RouteId: ""} Defensive patterns
Strategy: validation
Validate before calling
if newCtx.IsRouter && newCtx.RouteId != "" {
return fmt.Errorf("router token context must not set RouteId")
} Type guard
func validRouterContext(c *wshrpc.RpcContext) bool {
return c.IsRouter && c.RouteId == "" && !c.ProcRoute
} Try / catch
if _, err := validateRpcContextFromAuth(newCtx); err != nil {
// rebuild and re-mint the token with a router context (RouteId empty)
} Prevention
- Use dedicated constructors for router vs leaf RpcContext
- Unit-test token minting for both roles
- Never hand-merge leaf and router context fields
When it happens
Trigger: Authenticating with a token whose RpcContext has IsRouter:true and RouteId != "".
Common situations: Client code confusing its own route id with router identity when building the token; copy-pasted context structs between leaf and router clients.
Related errors
- error extracting socket name from JWT: %v
- invalid context, router cannot have a proc-route
- file %s contains binary data and cannot be uploaded as text
- file %s exceeds maximum size of %s for %s files
- unknown --view %q; try one of: term, web, preview, edit, sys
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/9da0df2bc9e0c502.
Report an issue: GitHub.