{"record":{"id":"70b50619203c5da5","repo":"wavetermdev/waveterm","slug":"failed-to-verify-job-auth-token-w","errorCode":null,"errorMessage":"failed to verify job auth token: %w","messagePattern":"failed to verify job auth token: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/wshutil/wshrouter_controlimpl.go","lineNumber":280,"sourceCode":"\t\tjob, err := wstore.DBMustGet[*waveobj.Job](ctx, data.JobId)\n\t\tif err != nil {\n\t\t\tlog.Printf(\"wshrouter authenticate-jobmanager error linkid=%d jobid=%q: failed to get job: %v\", linkId, data.JobId, err)\n\t\t\treturn fmt.Errorf(\"failed to get job: %w\", err)\n\t\t}\n\n\t\tif job.JobAuthToken != data.JobAuthToken {\n\t\t\tlog.Printf(\"wshrouter authenticate-jobmanager error linkid=%d jobid=%q: invalid jobauthtoken\", linkId, data.JobId)\n\t\t\treturn fmt.Errorf(\"invalid jobauthtoken\")\n\t\t}\n\t} else {\n\t\twshRpc := GetWshRpcFromContext(ctx)\n\t\tif wshRpc == nil {\n\t\t\treturn fmt.Errorf(\"no wshrpc in context\")\n\t\t}\n\t\t_, err := wshRpc.SendRpcRequest(wshrpc.Command_AuthenticateJobManagerVerify, data, &wshrpc.RpcOpts{Route: ControlRootRoute})\n\t\tif err != nil {\n\t\t\tlog.Printf(\"wshrouter authenticate-jobmanager error linkid=%d jobid=%q: failed to verify job auth token: %v\", linkId, data.JobId, err)\n\t\t\treturn fmt.Errorf(\"failed to verify job auth token: %w\", err)\n\t\t}\n\t}\n\n\trouteId := MakeJobRouteId(data.JobId)\n\tlog.Printf(\"wshrouter authenticate-jobmanager success linkid=%d jobid=%q routeid=%q\", linkId, data.JobId, routeId)\n\timpl.Router.trustLink(linkId, LinkKind_Leaf)\n\timpl.Router.bindRoute(linkId, routeId, true)\n\n\treturn nil\n}\n\nfunc validateRpcContextFromAuth(newCtx *wshrpc.RpcContext) (string, error) {\n\tif newCtx == nil {\n\t\treturn \"\", fmt.Errorf(\"no context found in jwt token\")\n\t}\n\tif newCtx.IsRouter && newCtx.RouteId != \"\" {\n\t\treturn \"\", fmt.Errorf(\"invalid context, router cannot have a routeid\")\n\t}","sourceCodeStart":262,"sourceCodeEnd":298,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/wshutil/wshrouter_controlimpl.go#L262-L298","documentation":"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.","triggerScenarios":"Non-root router calling SendRpcRequest(Command_AuthenticateJobManagerVerify, ..., Route: ControlRootRoute) and the RPC returns an error.","commonSituations":"Root rejected the token (invalid jobauthtoken upstream); ControlRootRoute unreachable because the link to the root is down; timeouts.","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"],"exampleFix":"// before\n// retry blindly with the same token\n// after\njob, _ := wstore.DBGet[*waveobj.Job](ctx, jobId)\nif job.JobAuthToken != token { /* refresh token before retrying verify */ }","handlingStrategy":"retry","validationCode":"// no pre-call check possible; ensure the root route is registered\nif !router.HasRoute(wshutil.ControlRootRoute) {\n    return fmt.Errorf(\"control root route unavailable\")\n}","typeGuard":null,"tryCatchPattern":"err := impl.AuthenticateJobManagerCommand(ctx, data)\nif err != nil && strings.Contains(err.Error(), \"failed to verify job auth token\") {\n    // inspect wrapped cause; retry after reconnecting to control root\n}","preventionTips":["Monitor control-root link health","Refresh tokens before retrying verify","Log the wrapped cause for diagnosis"],"tags":["wsh","rpc","network","authentication"],"backgroundTag":"rpc-forward-failed","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}