wavetermdev/waveterm · error
no routeid
Error message
no routeid
What it means
After passing the IsRouter check, extractTokenData calls entry.RpcContext.GenerateRouteId() and requires a non-empty route id for leaf connections. An empty result means the stored RpcContext is a leaf that carries neither a RouteId nor a ProcRoute combination that produces a route id — the entry is effectively unusable for binding a route on the router.
Source
Thrown at pkg/wshutil/wshrouter_controlimpl.go:137
return rtnData, nil
}
func extractTokenData(token string) (wshrpc.CommandAuthenticateRtnData, error) {
entry := shellutil.GetAndRemoveTokenSwapEntry(token)
if entry == nil {
return wshrpc.CommandAuthenticateRtnData{}, fmt.Errorf("no token entry found")
}
_, err := validateRpcContextFromAuth(entry.RpcContext)
if err != nil {
return wshrpc.CommandAuthenticateRtnData{}, err
}
if entry.RpcContext.IsRouter {
return wshrpc.CommandAuthenticateRtnData{}, fmt.Errorf("cannot auth router via token")
}
routeId := entry.RpcContext.GenerateRouteId()
if routeId == "" {
return wshrpc.CommandAuthenticateRtnData{}, fmt.Errorf("no routeid")
}
return wshrpc.CommandAuthenticateRtnData{
RouteId: routeId,
Env: entry.Env,
InitScriptText: entry.ScriptText,
RpcContext: entry.RpcContext,
}, nil
}
func (impl *WshRouterControlImpl) AuthenticateTokenVerifyCommand(ctx context.Context, data wshrpc.CommandAuthenticateTokenData) (wshrpc.CommandAuthenticateRtnData, error) {
if !impl.Router.IsRootRouter() {
return wshrpc.CommandAuthenticateRtnData{}, fmt.Errorf("authenticatetokenverify can only be called on root router")
}
if data.Token == "" {
return wshrpc.CommandAuthenticateRtnData{}, fmt.Errorf("no token in authenticatetoken message")
}
rtnData, err := extractTokenData(data.Token)View on GitHub (pinned to a4447c1563)
Solutions
- Re-mint the token ensuring RpcContext.RouteId is set (or ProcRoute is used appropriately) before swapping.
- Validate the RpcContext on the minting side with the same rules as validateRpcContextFromAuth (leaf must have a routeid).
- Check that token serialization/deserialization between processes preserves the RouteId field (no omitempty mismatches).
Example fix
// before
rpcCtx := &wshrpc.RpcContext{IsRouter: false} // no RouteId -> "no routeid"
// after
rpcCtx := &wshrpc.RpcContext{IsRouter: false, RouteId: "conn-abc123"} Defensive patterns
Strategy: validation
Validate before calling
// validate before minting, mirroring validateRpcContextFromAuth
if !rpcCtx.IsRouter && rpcCtx.RouteId == "" && !rpcCtx.ProcRoute {
return fmt.Errorf("leaf RpcContext requires a RouteId or ProcRoute")
} Prevention
- Always set RouteId on leaf RpcContexts when minting tokens
- Reuse the library's validateRpcContextFromAuth on the minting side
- Check struct tags (omitempty) so serialization never drops RouteId
When it happens
Trigger: AuthenticateTokenCommand / AuthenticateTokenVerifyCommand with a token whose RpcContext has IsRouter=false but no RouteId (and no ProcRoute flag), so GenerateRouteId returns "".
Common situations: Hand-constructed RpcContext in custom token-minting scripts missing the RouteId field; a version mismatch where the minting side omits a field the verify side requires; JSON serialization dropping the field.
Related errors
- error setting up rpc client: %w
- error making jwt token: %w
- no token entry found
- cannot auth router via token
- no token in authenticatetoken message
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/c9f8f869ed186f12.
Report an issue: GitHub.