{"record":{"id":"ee884e3995a7d3a1","repo":"Kuberwastaken/claurst","slug":"remote-settings-unexpected-response-shape","errorCode":null,"errorMessage":"Remote settings: unexpected response shape","messagePattern":"Remote settings: unexpected response shape","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-rust/crates/core/src/remote_settings.rs","lineNumber":239,"sourceCode":"                anyhow::bail!(\"Remote settings: not authorized ({})\", status);\r\n            }\r\n            other => {\r\n                anyhow::bail!(\"Remote settings: unexpected status {}\", other);\r\n            }\r\n        }\r\n\r\n        let body: Value = resp.json().await?;\r\n\r\n        // Try to parse as the expected response shape, but be permissive —\r\n        // accept raw settings object if the wrapper is missing.\r\n        let (settings, _checksum) = if let Ok(parsed) =\r\n            serde_json::from_value::<RemoteSettingsResponse>(body.clone())\r\n        {\r\n            (parsed.settings, parsed.checksum)\r\n        } else if body.is_object() {\r\n            (body, None)\r\n        } else {\r\n            anyhow::bail!(\"Remote settings: unexpected response shape\");\r\n        };\r\n\r\n        Ok(Some(settings))\r\n    }\r\n\r\n    /// Fetch settings with exponential-backoff retry.\r\n    ///\r\n    /// On success returns the new settings value (or `None` for 304).\r\n    /// On failure after all retries, returns the last error.\r\n    pub async fn fetch_with_retry(&self, cached_checksum: Option<&str>) -> Result<Option<Value>> {\r\n        let mut last_err = anyhow::anyhow!(\"No attempts made\");\r\n        for attempt in 1..=(DEFAULT_MAX_RETRIES + 1) {\r\n            match self.fetch_once(cached_checksum).await {\r\n                Ok(v) => return Ok(v),\r\n                Err(e) => {\r\n                    // Auth errors: don't retry\r\n                    let msg = e.to_string();\r\n                    if msg.contains(\"not authorized\") || msg.contains(\"No authentication\") {\r","sourceCodeStart":221,"sourceCodeEnd":257,"githubUrl":"https://github.com/Kuberwastaken/claurst/blob/b0637c97ec34144387cbf2f74f65df6d16a6cef1/src-rust/crates/core/src/remote_settings.rs#L221-L257","documentation":"The remote-settings response body parsed neither as the expected RemoteSettingsResponse wrapper object nor as a bare settings object (the parser is deliberately permissive and tries both shapes). The server returned 200 but with a JSON body that fits neither contract.","triggerScenarios":"Thrown at src-rust/crates/core/src/remote_settings.rs:239 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Log or curl the raw response body to see what the endpoint actually returned","Confirm the settings endpoint version matches what this client expects","Fall back to cached/local settings until the server shape is fixed"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"b0637c97ec34144387cbf2f74f65df6d16a6cef1","analyzedAt":"2026-09-10T00:24:58.650Z","contentChangedAt":"2026-09-10T00:24:58.650Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}