wavetermdev/waveterm · error
failed to verify job auth token: %w
Error message
failed to verify job auth token: %w
What it means
The forwarded Command_AuthenticateJobManagerVerify request to the control root failed. The underlying RPC error is wrapped; causes include the root rejecting the job/token (invalid token, unknown job) or transport/routing failures.
Source
Thrown at pkg/wshutil/wshrouter_controlimpl.go:280
job, err := wstore.DBMustGet[*waveobj.Job](ctx, data.JobId)
if err != nil {
log.Printf("wshrouter authenticate-jobmanager error linkid=%d jobid=%q: failed to get job: %v", linkId, data.JobId, err)
return fmt.Errorf("failed to get job: %w", err)
}
if job.JobAuthToken != data.JobAuthToken {
log.Printf("wshrouter authenticate-jobmanager error linkid=%d jobid=%q: invalid jobauthtoken", linkId, data.JobId)
return fmt.Errorf("invalid jobauthtoken")
}
} else {
wshRpc := GetWshRpcFromContext(ctx)
if wshRpc == nil {
return fmt.Errorf("no wshrpc in context")
}
_, err := wshRpc.SendRpcRequest(wshrpc.Command_AuthenticateJobManagerVerify, data, &wshrpc.RpcOpts{Route: ControlRootRoute})
if err != nil {
log.Printf("wshrouter authenticate-jobmanager error linkid=%d jobid=%q: failed to verify job auth token: %v", linkId, data.JobId, err)
return fmt.Errorf("failed to verify job auth token: %w", err)
}
}
routeId := MakeJobRouteId(data.JobId)
log.Printf("wshrouter authenticate-jobmanager success linkid=%d jobid=%q routeid=%q", linkId, data.JobId, routeId)
impl.Router.trustLink(linkId, LinkKind_Leaf)
impl.Router.bindRoute(linkId, routeId, true)
return nil
}
func validateRpcContextFromAuth(newCtx *wshrpc.RpcContext) (string, error) {
if newCtx == nil {
return "", fmt.Errorf("no context found in jwt token")
}
if newCtx.IsRouter && newCtx.RouteId != "" {
return "", fmt.Errorf("invalid context, router cannot have a routeid")
}View on GitHub (pinned to a4447c1563)
Solutions
- Check the wrapped error to see whether the root rejected the token or the route failed
- Verify connectivity to the control root and retry authentication
- Re-sync job credentials so the root's stored token matches what the client sends
Example fix
// before
// retry blindly with the same token
// after
job, _ := wstore.DBGet[*waveobj.Job](ctx, jobId)
if job.JobAuthToken != token { /* refresh token before retrying verify */ } Defensive patterns
Strategy: retry
Validate before calling
// no pre-call check possible; ensure the root route is registered
if !router.HasRoute(wshutil.ControlRootRoute) {
return fmt.Errorf("control root route unavailable")
} Try / catch
err := impl.AuthenticateJobManagerCommand(ctx, data)
if err != nil && strings.Contains(err.Error(), "failed to verify job auth token") {
// inspect wrapped cause; retry after reconnecting to control root
} Prevention
- Monitor control-root link health
- Refresh tokens before retrying verify
- Log the wrapped cause for diagnosis
When it happens
Trigger: Non-root router calling SendRpcRequest(Command_AuthenticateJobManagerVerify, ..., Route: ControlRootRoute) and the RPC returns an error.
Common situations: Root rejected the token (invalid jobauthtoken upstream); ControlRootRoute unreachable because the link to the root is down; timeouts.
Related errors
- failed to list workspaces: %v
- failed to list blocks from all %d workspace(s)
- getting variable: %w
- getting variables: %w
- getting connected job ids: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/70b50619203c5da5.
Report an issue: GitHub.