{"record":{"id":"e956959c7e4ea127","repo":"AlexxIT/go2rtc","slug":"failed-to-load-hub-config-w-e95695","errorCode":null,"errorMessage":"failed to load hub config: %w","messagePattern":"failed to load hub config: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/tuya/smart_api.go","lineNumber":310,"sourceCode":"\t}\n\n\treturn client, nil\n}\n\n// WebRTC Flow\nfunc (c *TuyaSmartApiClient) Init() error {\n\tif err := c.initToken(); err != nil {\n\t\treturn fmt.Errorf(\"failed to initialize token: %w\", err)\n\t}\n\n\twebrtcConfig, err := c.loadWebrtcConfig()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to load webrtc config: %w\", err)\n\t}\n\n\thubConfig, err := c.loadHubConfig()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to load hub config: %w\", err)\n\t}\n\n\tif err := c.mqtt.Start(hubConfig, webrtcConfig, c.skill.WebRTC); err != nil {\n\t\treturn fmt.Errorf(\"failed to start MQTT: %w\", err)\n\t}\n\n\tif c.skill.LowPower > 0 {\n\t\t_ = c.mqtt.WakeUp(c.localKey)\n\t}\n\n\treturn nil\n}\n\nfunc (c *TuyaSmartApiClient) GetStreamUrl(streamType string) (streamUrl string, err error) {\n\treturn \"\", errors.New(\"not supported\")\n}\n\nfunc (c *TuyaSmartApiClient) GetAppInfo() (*AppInfoResponse, error) {","sourceCodeStart":292,"sourceCodeEnd":328,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/pkg/tuya/smart_api.go#L292-L328","documentation":"Wraps a failure from loadHubConfig() during Tuya smart API startup. The hub config (MQTT broker address, credentials, topic routing) is fetched from the Tuya cloud after the webrtc config. If that HTTP call fails, Start() aborts because the MQTT connection cannot be established without it.","triggerScenarios":"TuyaSmartAPI Start() when loadHubConfig()'s cloud request fails: invalid credentials, wrong region endpoint, token rejected mid-flow, malformed response from Tuya, or network failure between token init and hub-config fetch.","commonSituations":"Tuya cloud returns 401 because accessKey was rotated while the process held an old token; account moved to a different data center region; transient Tuya API outage; response shape changed after a Tuya API update.","solutions":["Log the wrapped inner error to distinguish auth failure vs network vs unmarshal error","Re-check accessId/accessKey and region; rotate credentials if recently changed in the Tuya IoT console","Ensure initToken succeeded with a valid token before hub config fetch","Retry with backoff on transient 5xx / network errors","Update go2rtc if Tuya changed the hub-config API response format"],"exampleFix":"// before\nif err := c.Start(); err != nil { return err } // opaque failure\n// after\nif err := c.Start(); err != nil {\n    if strings.Contains(err.Error(), \"failed to load hub config\") {\n        // refresh token / re-auth, then retry\n        _ = c.initToken()\n    }\n    return fmt.Errorf(\"tuya: %w\", err)\n}","handlingStrategy":"try-catch","validationCode":"// Go: sanity-check credentials/region before Start\nif accessID == \"\" || accessKey == \"\" { return errors.New(\"tuya credentials missing\") }\nif !validRegion(region) { return fmt.Errorf(\"invalid region %q\", region) }","typeGuard":"func hubConfigValid(cfg *tuya.HubConfig) bool { return cfg != nil && cfg.Broker != \"\" }","tryCatchPattern":"if err := c.Start(); err != nil {\n    if strings.Contains(err.Error(), \"failed to load hub config\") {\n        _ = c.initToken() // refresh then retry once\n    }\n    return err\n}","preventionTips":["Rotate credentials centrally and restart clients after rotation","Add retry with backoff around Start() for transient 5xx","Confirm region matches the Tuya data center hosting your devices","Monitor Tuya cloud status for outages"],"tags":["tuya","mqtt","cloud-api","config"],"backgroundTag":"http-request-failed","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"}