wavetermdev/waveterm · error
error making jwt token: %w
Error message
error making jwt token: %w
What it means
Before launching the remote shell, the controller mints a JWT token (wshutil.MakeClientJWTToken) that authenticates the spawned shell's wsh RPC back to the app, injected via the swap token environment. This error means local token generation failed — typically missing signing key material or malformed RpcContext.
Source
Thrown at pkg/blockcontroller/durableshellcontroller.go:261
return "", fmt.Errorf("connection %q not found", connName)
}
connRoute := wshutil.MakeConnectionRouteId(connName)
remoteInfo, err := wshclient.RemoteGetInfoCommand(wshclient.GetBareRpcClient(), &wshrpc.RpcOpts{Route: connRoute, Timeout: 2000})
if err != nil {
return "", fmt.Errorf("unable to obtain remote info from connserver: %w", err)
}
shellType := shellutil.GetShellTypeFromShellPath(remoteInfo.Shell)
swapToken := makeSwapToken(ctx, ctx, dsc.BlockId, blockMeta, connName, shellType)
sockName := wavebase.GetPersistentRemoteSockName(wstore.GetClientId())
rpcContext := wshrpc.RpcContext{
ProcRoute: true,
SockName: sockName,
BlockId: dsc.BlockId,
Conn: connName,
}
jwtStr, err := wshutil.MakeClientJWTToken(rpcContext)
if err != nil {
return "", fmt.Errorf("error making jwt token: %w", err)
}
swapToken.RpcContext = &rpcContext
swapToken.Env[wshutil.WaveJwtTokenVarName] = jwtStr
cmdOpts := shellexec.CommandOptsType{
Interactive: true,
Login: true,
Cwd: cwd,
SwapToken: swapToken,
ForceJwt: blockMeta.GetBool(waveobj.MetaKey_CmdJwt, false),
}
jobId, err := shellexec.StartRemoteShellJob(ctx, ctx, termSize, cmdStr, cmdOpts, conn, dsc.BlockId)
if err != nil {
return "", fmt.Errorf("failed to start durable shell: %w", err)
}
return jobId, nil
}
View on GitHub (pinned to a4447c1563)
Solutions
- Check that the local wave config directory and its key material exist and are readable.
- Reset the app's key/config state (re-initialize config) if keys are corrupt.
- Verify RpcContext fields (SockName, BlockId, Conn) are non-empty and correct.
- Inspect the wrapped inner error for the exact crypto/token failure.
Example fix
// before
rpcContext := wshrpc.RpcContext{ProcRoute: true} // missing Route/fields, token gen fails
// after
rpcContext := wshrpc.RpcContext{ProcRoute: true, Route: connRoute, BlockId: dsc.BlockId, SockName: sockName, Conn: connName}
jwtStr, err := wshutil.MakeClientJWTToken(rpcContext) Defensive patterns
Strategy: try-catch
Try / catch
if _, err := controller.Start(ctx, meta, rtOpts, false); err != nil {
if strings.Contains(err.Error(), "jwt token") {
// regenerate/repair local key material, then retry
}
return err
} Prevention
- Do not hand-edit or copy partial wave config/key files between machines
- Keep all RpcContext fields populated when constructing tokens
- Back up and restore config directories atomically
- Upgrade wsh and the app together to keep token formats compatible
When it happens
Trigger: MakeClientJWTToken returns an error: the client's signing key/secret is missing or unreadable, or the constructed RpcContext (ProcRoute, SockName, BlockId, Conn) is invalid for token claims.
Common situations: Corrupted or missing local key/config files after a bad install or profile copy; running in a sandbox/home-dir without the expected wave config; clock/claims issues in extreme cases.
Related errors
- error setting up rpc client: %w
- error making jwt token: %w
- failed to generate job access token: %w
- failed to set public key: %w
- error validating token: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/3716adeecd78049b.
Report an issue: GitHub.