wavetermdev/waveterm · error
error making jwt token: %w
Error message
error making jwt token: %w
What it means
Wraps a failure from wshutil.MakeClientJWTToken while building the auth token injected into the environment for a WSL shell process. The JWT authenticates the wsh client back to Wave over the domain socket; without it the spawned shell cannot speak the wsh RPC protocol.
Source
Thrown at pkg/blockcontroller/shellcontroller.go:444
blocklogger.Debugf(logCtx, "[conndebug] created swaptoken: %s\n", swapToken.Token)
if connUnion.ConnType == ConnType_Wsl {
wslConn := connUnion.WslConn
if !connUnion.WshEnabled {
shellProc, err = shellexec.StartWslShellProcNoWsh(ctx, rc.TermSize, cmdStr, cmdOpts, wslConn)
if err != nil {
return nil, err
}
} else {
sockName := wslConn.GetDomainSocketName()
rpcContext := wshrpc.RpcContext{
ProcRoute: true,
SockName: sockName,
BlockId: bc.BlockId,
Conn: wslConn.GetName(),
}
jwtStr, err := wshutil.MakeClientJWTToken(rpcContext)
if err != nil {
return nil, fmt.Errorf("error making jwt token: %w", err)
}
swapToken.RpcContext = &rpcContext
swapToken.Env[wshutil.WaveJwtTokenVarName] = jwtStr
shellProc, err = shellexec.StartWslShellProc(ctx, rc.TermSize, cmdStr, cmdOpts, wslConn)
if err != nil {
wslConn.SetWshError(err)
wslConn.WshEnabled.Store(false)
blocklogger.Infof(logCtx, "[conndebug] error starting wsl shell proc with wsh: %v\n", err)
blocklogger.Infof(logCtx, "[conndebug] attempting install without wsh\n")
shellProc, err = shellexec.StartWslShellProcNoWsh(ctx, rc.TermSize, cmdStr, cmdOpts, wslConn)
if err != nil {
return nil, err
}
}
}
} else if connUnion.ConnType == ConnType_Ssh {
conn := connUnion.SshConn
if !connUnion.WshEnabled {View on GitHub (pinned to a4447c1563)
Solutions
- Verify Wave's key/secret files exist in the data directory with correct permissions and regenerate them if missing
- Ensure HOME/XDG paths point to the same data directory used when keys were created
- Restart Wave so key initialization runs again
- If migrating machines, copy the whole ~/.waveterm data dir (including key material), not just config
Example fix
// before: signing with whatever key is present
jwtStr, err := wshutil.MakeClientJWTToken(rpcContext)
// after: ensure key material is initialized first
if err := wshutil.EnsureKeyInitialized(); err != nil {
return nil, fmt.Errorf("key material missing, reinit wave data dir: %w", err)
}
jwtStr, err := wshutil.MakeClientJWTToken(rpcContext) Defensive patterns
Strategy: try-catch
Validate before calling
// ensure signing key exists before starting shells
if _, err := wshutil.GetWaveKey(); err != nil {
return fmt.Errorf("wave key unavailable: %w", err)
} Try / catch
proc, err := bc.setupAndStartShellProcess(logCtx, rc, blockMeta)
if err != nil && strings.Contains(err.Error(), "error making jwt token") {
// reinit key material and retry once
} Prevention
- Verify key files exist with 600 permissions in the wave data dir
- Copy entire data dir (keys included) when migrating machines
- Restart Wave after any change to HOME/data-dir env vars
When it happens
Trigger: StartWslShellProc path: wshutil.MakeClientJWTToken(rpcContext) returns an error, typically because the Wave key/secret material needed to sign the token is missing or unreadable.
Common situations: ~/.waveterm secret/key files missing, zero-length, or with wrong permissions (e.g. app data copied between machines/users); running Wave with a different HOME so the key isn't found; first-run initialization interrupted so keys were never generated.
Related errors
- error extracting socket name from JWT: %v
- error making jwt token: %w
- failed to set public key: %w
- error validating token: %w
- no context found in jwt token
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/8b06305d0b33a8e0.
Report an issue: GitHub.