wavetermdev/waveterm · error

no token in authenticatetoken message

Error message

no token in authenticatetoken message

What it means

AuthenticateTokenVerifyCommand requires data.Token to be a non-empty string before it will attempt verification. An empty Token field in CommandAuthenticateTokenData is rejected immediately with this message.

Solutions

  1. Check the token source (env var, file, CLI flag) and confirm it was populated before building CommandAuthenticateTokenData.
  2. Add a client-side empty-string guard before sending the RPC.
  3. Re-run the token issuance step if the token was never minted.

Example fix

// before
data := wshrpc.CommandAuthenticateTokenData{Token: tokenFromEnv} // tokenFromEnv == ""
// after
if tokenFromEnv == "" {
    return fmt.Errorf("connection token is empty; re-run token issuance")
}
data := wshrpc.CommandAuthenticateTokenData{Token: tokenFromEnv}
Defensive patterns

Strategy: validation

Validate before calling

if data.Token == "" {
    return fmt.Errorf("token must be non-empty before calling authenticatetokenverify")
}

Prevention

When it happens

Trigger: Calling AuthenticateTokenVerifyCommand with wshrpc.CommandAuthenticateTokenData{Token: ""} — typically the token variable was never populated before the RPC was sent.

Common situations: Env var holding the token not set when constructing the request; a code path that reads the token asynchronously and races ahead with an empty value; copy/paste loss when scripting wsh connections.

Understand the failure class

Related errors


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

Appendix: source

Thrown at pkg/wshutil/wshrouter_controlimpl.go:152

	}
	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)
	if err != nil {
		log.Printf("wshrouter authenticate-token-verify error: %v", err)
		return wshrpc.CommandAuthenticateRtnData{}, err
	}

	log.Printf("wshrouter authenticate-token-verify success routeid=%q", rtnData.RouteId)
	return rtnData, nil
}

func (impl *WshRouterControlImpl) AuthenticateTokenCommand(ctx context.Context, data wshrpc.CommandAuthenticateTokenData) (wshrpc.CommandAuthenticateRtnData, error) {
	handler := GetRpcResponseHandlerFromContext(ctx)
	if handler == nil {
		return wshrpc.CommandAuthenticateRtnData{}, fmt.Errorf("no response handler in context")
	}
	linkId := handler.GetIngressLinkId()

View on GitHub (pinned to a4447c1563)