wavetermdev/waveterm · error
no token entry found
Error message
no token entry found
What it means
extractTokenData looks up the token string in the in-memory token-swap store via shellutil.GetAndRemoveTokenSwapEntry. Tokens issued for wsh connection are single-use: the entry is consumed (removed) on first successful verification. If the token string is not found in the store, this error is returned, meaning the token is unknown, already consumed, or was never issued by this process.
Source
Thrown at pkg/wshutil/wshrouter_controlimpl.go:126
}
rtnData := wshrpc.CommandAuthenticateRtnData{RouteId: routeId}
if newCtx.IsRouter {
log.Printf("wshrouter authenticate success linkid=%d (router)", linkId)
impl.Router.trustLink(linkId, LinkKind_Router)
} else {
log.Printf("wshrouter authenticate success linkid=%d routeid=%q", linkId, routeId)
impl.Router.trustLink(linkId, LinkKind_Leaf)
impl.Router.bindRoute(linkId, routeId, true)
}
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,
}, nilView on GitHub (pinned to a4447c1563)
Solutions
- Generate a fresh token from the server and retry — token-swap entries are single-use and cannot be reused after the first verification.
- Confirm wsh is connecting to the same server process that minted the token (a restart wipes the in-memory token map).
- Ensure the token string is passed verbatim (no truncation or shell-mangled characters).
- If automated retries are in place, re-mint a token per attempt rather than caching one.
Example fix
// before err := conn.AuthenticateToken(ctx, cachedToken) // second use -> gone // after freshToken := server.MintConnectionToken() // mint a new single-use token each attempt err := conn.AuthenticateToken(ctx, freshToken)
Defensive patterns
Strategy: retry
Try / catch
// Go: on this error, re-mint the token and retry once
rtn, err := conn.AuthenticateToken(ctx, token)
if err != nil && strings.Contains(err.Error(), "no token entry found") {
token = mintFreshConnectionToken()
rtn, err = conn.AuthenticateToken(ctx, token)
} Prevention
- Treat token-swap tokens as strictly single-use — never reuse after a successful auth
- Re-mint a token for every connection attempt in automation
- Avoid server restarts between minting and consuming a token
When it happens
Trigger: Calling AuthenticateTokenCommand or AuthenticateTokenVerifyCommand with a token that (a) was never minted by shellutil token-swap, (b) was already redeemed once (single-use entries are removed on Get), or (c) was minted in a different server process/restart so the in-memory map no longer has it.
Common situations: Retrying a wsh connection after a first attempt already consumed the token; server restarted between token issuance and use; wsh connecting to the wrong server instance (token from another machine); copy of a token used by two clients.
Related errors
- error setting up rpc client: %w
- error making jwt token: %w
- error validating token: %w
- cannot auth router via token
- no routeid
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/27998c4c54e0fc08.
Report an issue: GitHub.