{"record":{"id":"3b9211886a3688fa","repo":"wavetermdev/waveterm","slug":"no-jobid-in-authenticatejobmanager-message","errorCode":null,"errorMessage":"no jobid in authenticatejobmanager message","messagePattern":"no jobid in authenticatejobmanager message","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/wshutil/wshrouter_controlimpl.go","lineNumber":223,"sourceCode":"\t\treturn wshrpc.CommandAuthenticateRtnData{}, fmt.Errorf(\"no rpccontext in token response\")\n\t}\n\tif rtnData.RouteId == \"\" {\n\t\treturn wshrpc.CommandAuthenticateRtnData{}, fmt.Errorf(\"no routeid in token response\")\n\t}\n\tlog.Printf(\"wshrouter authenticate-token success linkid=%d routeid=%q\", linkId, rtnData.RouteId)\n\timpl.Router.trustLink(linkId, LinkKind_Leaf)\n\timpl.Router.bindRoute(linkId, rtnData.RouteId, true)\n\n\treturn rtnData, nil\n}\n\nfunc (impl *WshRouterControlImpl) AuthenticateJobManagerVerifyCommand(ctx context.Context, data wshrpc.CommandAuthenticateJobManagerData) error {\n\tif !impl.Router.IsRootRouter() {\n\t\treturn fmt.Errorf(\"authenticatejobmanagerverify can only be called on root router\")\n\t}\n\n\tif data.JobId == \"\" {\n\t\treturn fmt.Errorf(\"no jobid in authenticatejobmanager message\")\n\t}\n\tif data.JobAuthToken == \"\" {\n\t\treturn fmt.Errorf(\"no jobauthtoken in authenticatejobmanager message\")\n\t}\n\n\tjob, err := wstore.DBMustGet[*waveobj.Job](ctx, data.JobId)\n\tif err != nil {\n\t\tlog.Printf(\"wshrouter authenticate-jobmanager-verify error jobid=%q: failed to get job: %v\", data.JobId, err)\n\t\treturn fmt.Errorf(\"failed to get job: %w\", err)\n\t}\n\n\tif job.JobAuthToken != data.JobAuthToken {\n\t\tlog.Printf(\"wshrouter authenticate-jobmanager-verify error jobid=%q: invalid jobauthtoken\", data.JobId)\n\t\treturn fmt.Errorf(\"invalid jobauthtoken\")\n\t}\n\n\tlog.Printf(\"wshrouter authenticate-jobmanager-verify success jobid=%q\", data.JobId)\n\treturn nil","sourceCodeStart":205,"sourceCodeEnd":241,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/wshutil/wshrouter_controlimpl.go#L205-L241","documentation":"The AuthenticateJobManagerVerify RPC payload must carry a non-empty JobId identifying the job record to verify against. An empty JobId means the caller built CommandAuthenticateJobManagerData without setting JobId, so there is nothing to look up in wstore.","triggerScenarios":"Sending Command_AuthenticateJobManagerVerify with CommandAuthenticateJobManagerData{JobId: \"\"} — e.g. job id never assigned, zero-value struct passed, or field lost during serialization.","commonSituations":"Job creation failed upstream so the job (and its id) never got persisted before verification was attempted; copy-paste building the data struct omitting JobId; JSON field name mismatch dropping the value.","solutions":["Set data.JobId from the created job record before calling the RPC.","Confirm the job was successfully created and its id persisted before attempting verification.","Check the JSON/RPC serialization to ensure the jobid field is transmitted.","Validate the payload client-side and fail fast before sending the RPC."],"exampleFix":"// before\n_, err := wshRpc.SendRpcRequest(wshrpc.Command_AuthenticateJobManagerVerify, wshrpc.CommandAuthenticateJobManagerData{JobAuthToken: tok}, opts)\n// after\nif data.JobId == \"\" {\n    return fmt.Errorf(\"cannot verify job: JobId is empty\")\n}\n_, err := wshRpc.SendRpcRequest(wshrpc.Command_AuthenticateJobManagerVerify, data, opts)","handlingStrategy":"validation","validationCode":"if data.JobId == \"\" {\n    return fmt.Errorf(\"JobId is required for job-manager verification\")\n}\n// safe to call RPC","typeGuard":"func jobDataComplete(d wshrpc.CommandAuthenticateJobManagerData) bool {\n    return d.JobId != \"\"\n}","tryCatchPattern":"err := verifyJobManager(ctx, data)\nif err != nil && strings.Contains(err.Error(), \"no jobid in authenticatejobmanager message\") {\n    return fmt.Errorf(\"caller bug: build the data struct with a real JobId: %w\", err)\n}","preventionTips":["Construct CommandAuthenticateJobManagerData only via a constructor that sets JobId.","Verify job creation succeeded and keep the returned id before verification.","Validate payload fields before every RPC send."],"tags":["validation","rpc","authentication"],"backgroundTag":"missing-required-argument","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}