{"record":{"id":"97e51ad3b1532623","repo":"AlexxIT/go2rtc","slug":"loginresp-errormsg-97e51a","errorCode":null,"errorMessage":"${loginResp.ErrorMsg}","messagePattern":"\\$\\{loginResp\\.ErrorMsg\\}","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"pkg/tuya/smart_api.go","lineNumber":468,"sourceCode":"\t\tloginUrl = fmt.Sprintf(\"https://%s/api/private/email/login\", c.baseUrl)\n\t\tloginReq.Email = c.email\n\t} else {\n\t\tloginUrl = fmt.Sprintf(\"https://%s/api/private/phone/login\", c.baseUrl)\n\t\tloginReq.Mobile = c.email\n\t}\n\n\tbody, err = c.request(\"POST\", loginUrl, loginReq)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar loginResp *PasswordLoginResponse\n\tif err := json.Unmarshal(body, &loginResp); err != nil {\n\t\treturn err\n\t}\n\n\tif !loginResp.Success {\n\t\treturn errors.New(loginResp.ErrorMsg)\n\t}\n\n\tc.mqttsUrl = fmt.Sprintf(\"ssl://%s:%d\", loginResp.Result.Domain.MobileMqttsUrl, loginResp.Result.Domain.MqttsPort)\n\tc.expireTime = time.Now().Unix() + 2*24*60*60 // 2 days in seconds\n\n\treturn nil\n}\n\nfunc (c *TuyaSmartApiClient) loadWebrtcConfig() (*WebRTCConfig, error) {\n\turl := fmt.Sprintf(\"https://%s/api/jarvis/config\", c.baseUrl)\n\n\tdata := SmartApiWebRTCConfigRequest{\n\t\tDevId:         c.deviceId,\n\t\tClientTraceId: fmt.Sprintf(\"%x\", rand.Int63()),\n\t}\n\n\tbody, err := c.request(\"POST\", url, data)\n\tif err != nil {","sourceCodeStart":450,"sourceCodeEnd":486,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/pkg/tuya/smart_api.go#L450-L486","documentation":"PasswordLogin returns this error when the Tuya password-login API responds with Success=false; loginResp.ErrorMsg (this endpoint's error field name) is passed to errors.New. The login failed, so MQTT URLs and expiry are never set and the client is unusable. The server's message is propagated unchanged.","triggerScenarios":"Calling the password-login flow when the response has Success=false — wrong credentials, account locked, or cloud-side rejection of the login request.","commonSituations":"Invalid/rotated Tuya password; account requires captcha or 2FA; wrong region; encrypted password built from a stale public key; Tuya cloud maintenance.","solutions":["Read ErrorMsg for the exact login failure reason and correct credentials first.","Re-run initToken to fetch a fresh public key before encrypting the password.","Verify account status (locked/2FA/captcha) in the Tuya app or developer console.","Confirm the region/endpoint matches the account's region.","Retry with backoff only for transient server messages."],"exampleFix":"// before\nif err := client.Login(); err != nil {\n    return err // raw ErrorMsg, no context\n}\n// after\nif err := client.Login(); err != nil {\n    return fmt.Errorf(\"tuya password login failed: %w\", err)\n}","handlingStrategy":"try-catch","validationCode":"if client.password == \"\" { return errors.New(\"password required\") }; ensure initToken() succeeded and key is fresh before Login()","typeGuard":null,"tryCatchPattern":"if err := client.Login(); err != nil {\n    if isAuthRelated(err.Error()) {\n        return fmt.Errorf(\"tuya login rejected: %w\", err) // fix creds, no retry\n    }\n    return fmt.Errorf(\"tuya login: %w\", err)\n}","preventionTips":["Always run initToken immediately before password login","Detect and surface captcha/2FA requirements","Verify region matches the account","Fail fast on auth errors; back off on server errors"],"tags":["api","tuya","authentication","login"],"backgroundTag":"authentication-required","analyzedSha":"c245815e75e2a5fd60b4290f12bfc04e55a984d3","analyzedAt":"2026-09-07T11:47:02.965Z","contentChangedAt":"2026-09-07T11:47:02.965Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}