AlexxIT/go2rtc · critical
${loginResp.ErrorMsg}
Error message
${loginResp.ErrorMsg} What it means
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.
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.
Example fix
// before
if err := client.Login(); err != nil {
return err // raw ErrorMsg, no context
}
// after
if err := client.Login(); err != nil {
return fmt.Errorf("tuya password login failed: %w", err)
} Defensive patterns
Strategy: try-catch
Validate before calling
if client.password == "" { return errors.New("password required") }; ensure initToken() succeeded and key is fresh before Login() Try / catch
if err := client.Login(); err != nil {
if isAuthRelated(err.Error()) {
return fmt.Errorf("tuya login rejected: %w", err) // fix creds, no retry
}
return fmt.Errorf("tuya login: %w", err)
} Prevention
- 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
When it happens
Trigger: Calling the password-login flow when the response has Success=false — wrong credentials, account locked, or cloud-side rejection of the login request.
Common situations: Invalid/rotated Tuya password; account requires captcha or 2FA; wrong region; encrypted password built from a stale public key; Tuya cloud maintenance.
Related errors
AI-assisted analysis of AlexxIT/go2rtc@c245815e75 (2026-09-07).
Data as JSON: /api/errors/97e51ad3b1532623.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/tuya/smart_api.go:468
loginUrl = fmt.Sprintf("https://%s/api/private/email/login", c.baseUrl)
loginReq.Email = c.email
} else {
loginUrl = fmt.Sprintf("https://%s/api/private/phone/login", c.baseUrl)
loginReq.Mobile = c.email
}
body, err = c.request("POST", loginUrl, loginReq)
if err != nil {
return err
}
var loginResp *PasswordLoginResponse
if err := json.Unmarshal(body, &loginResp); err != nil {
return err
}
if !loginResp.Success {
return errors.New(loginResp.ErrorMsg)
}
c.mqttsUrl = fmt.Sprintf("ssl://%s:%d", loginResp.Result.Domain.MobileMqttsUrl, loginResp.Result.Domain.MqttsPort)
c.expireTime = time.Now().Unix() + 2*24*60*60 // 2 days in seconds
return nil
}
func (c *TuyaSmartApiClient) loadWebrtcConfig() (*WebRTCConfig, error) {
url := fmt.Sprintf("https://%s/api/jarvis/config", c.baseUrl)
data := SmartApiWebRTCConfigRequest{
DevId: c.deviceId,
ClientTraceId: fmt.Sprintf("%x", rand.Int63()),
}
body, err := c.request("POST", url, data)
if err != nil {View on GitHub (pinned to c245815e75)