{"record":{"id":"58b37e898c25e351","repo":"AlexxIT/go2rtc","slug":"tuya","errorCode":null,"errorMessage":"tuya: ","messagePattern":"tuya: ","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/tuya/tuya.go","lineNumber":204,"sourceCode":"\treq.Header.Set(\"Content-Type\", \"application/json; charset=utf-8\")\n\treq.Header.Set(\"Accept\", \"*/*\")\n\treq.Header.Set(\"Origin\", fmt.Sprintf(\"https://%s\", serverHost))\n\treq.Header.Set(\"Referer\", fmt.Sprintf(\"https://%s/login\", serverHost))\n\treq.Header.Set(\"X-Requested-With\", \"XMLHttpRequest\")\n\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\n\tvar tokenResp tuya.LoginTokenResponse\n\tif err = json.NewDecoder(resp.Body).Decode(&tokenResp); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif !tokenResp.Success {\n\t\treturn nil, errors.New(\"tuya: \" + tokenResp.Msg)\n\t}\n\n\treturn &tokenResp, nil\n}\n\nfunc performLogin(client *http.Client, url string, loginReq tuya.PasswordLoginRequest, serverHost string) (*tuya.PasswordLoginResponse, error) {\n\tjsonData, err := json.Marshal(loginReq)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treq, err := http.NewRequest(\"POST\", url, bytes.NewBuffer(jsonData))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treq.Header.Set(\"Content-Type\", \"application/json; charset=utf-8\")\n\treq.Header.Set(\"Accept\", \"*/*\")","sourceCodeStart":186,"sourceCodeEnd":222,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/internal/tuya/tuya.go#L186-L222","documentation":"getLoginToken's guard on the Tuya cloud login response: the HTTP request and JSON decode succeeded, but the response body reports Success=false, and the server-provided Msg is appended after the 'tuya: ' prefix. The cause is server-side rejection of the login attempt — bad credentials, wrong app credentials, or an account issue described by Msg.","triggerScenarios":"The POST to the Tuya token endpoint returns success=false — invalid/missing access credentials (client key/secret), wrong region server host, or expired/revoked Tuya developer credentials.","commonSituations":"Misconfigured tuya_client_id/tuya_client_secret; using an endpoint for a different data center; Tuya developer account suspended; clock skew invalidating the signed request on the vendor side.","solutions":["Verify tuya client ID and secret are correct and active in the Tuya IoT platform","Confirm the server host/region matches where the account is registered","Check the returned Msg text (after the \"tuya: \" prefix) for the exact vendor reason","Ensure system clock is accurate since Tuya request signing is time-sensitive"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"token, err := getLoginToken(client, host, id, secret)\nif err != nil {\n\tvar apiErr string\n\tif strings.HasPrefix(err.Error(), \"tuya: \") {\n\t\tapiErr = strings.TrimPrefix(err.Error(), \"tuya: \")\n\t}\n\tlog.Printf(\"tuya token exchange failed: %s\", apiErr)\n}","preventionTips":["Verify client ID/secret in the Tuya IoT platform before deployment","Keep system clocks synced (signed requests are time-sensitive)","Match the endpoint host to the account region"],"tags":["go","tuya","authentication","api"],"backgroundTag":"api-error-response","analyzedSha":"c245815e75e2a5fd60b4290f12bfc04e55a984d3","analyzedAt":"2026-09-07T11:47:02.965Z","contentChangedAt":"2026-09-07T11:47:02.965Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}