{"record":{"id":"2e2d309486775622","repo":"AlexxIT/go2rtc","slug":"failed-to-decode-session-response-w","errorCode":null,"errorMessage":"failed to decode session response: %w","messagePattern":"failed to decode session response: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/ring/api.go","lineNumber":566,"sourceCode":"\treq.Header.Set(\"Accept\", \"application/json\")\n\treq.Header.Set(\"Authorization\", \"Bearer \"+c.authToken.AccessToken)\n\treq.Header.Set(\"hardware_id\", c.hardwareID)\n\treq.Header.Set(\"User-Agent\", \"android:com.ringapp\")\n\n\tresp, err := c.httpClient.Do(req)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode < 200 || resp.StatusCode >= 300 {\n\t\trespBody, _ := io.ReadAll(resp.Body)\n\t\treturn fmt.Errorf(\"session request failed with status %d: %s\", resp.StatusCode, string(respBody))\n\t}\n\n\tvar sessionResp SessionResponse\n\tif err := json.NewDecoder(resp.Body).Decode(&sessionResp); err != nil {\n\t\treturn fmt.Errorf(\"failed to decode session response: %w\", err)\n\t}\n\n\tc.session = &sessionResp\n\tc.sessionExpiry = time.Now().Add(sessionValidTime)\n\n\t// Aktualisiere den gecachten Client\n\tcacheMutex.Lock()\n\tclientCache[c.cacheKey] = c\n\tcacheMutex.Unlock()\n\n\treturn nil\n}\n\nfunc (c *RingApi) ensureAuth() error {\n\tc.authMutex.Lock()\n\tdefer c.authMutex.Unlock()\n\n\t// If token exists and is not expired, use it","sourceCodeStart":548,"sourceCodeEnd":584,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/pkg/ring/api.go#L548-L584","documentation":"The Ring session creation request returned a non-2xx status; the response body is included for diagnostics. Prevents the client from establishing an authenticated session (needed for subsequent API calls).","triggerScenarios":"Ring's session endpoint returns 2xx with a body that fails json.Decode into SessionResponse (schema drift, HTML error page behind a 200, truncated body).","commonSituations":"Ring API changes the session response shape; a proxy/captive portal returns a 200 HTML page; library version older than current Ring API contract.","solutions":["Log the raw response body to see what was actually returned","Update the ring client library to match the current API response schema","Check for proxies/captive portals rewriting the response","Inspect SessionResponse fields against the actual payload and adjust the struct"],"exampleFix":"null","handlingStrategy":"try-catch","validationCode":"// sanity-check raw body before decode:\n// if !json.Valid(rawBody) { fail early }","typeGuard":"func looksLikeSession(b []byte) bool {\n    var probe map[string]interface{}\n    return json.Unmarshal(b, &probe) == nil\n}","tryCatchPattern":"if err != nil {\n    if strings.Contains(err.Error(), \"failed to decode session response\") {\n        log.Printf(\"unexpected session payload; update library or check proxy\")\n    }\n    return err\n}","preventionTips":["Keep the client library current with Ring API changes","Check for proxies/captive portals that rewrite responses with 200 status","Log raw bodies on decode failures for diagnosis"],"tags":["json","decode","api-response","ring"],"backgroundTag":"json-unmarshal-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"}