{"record":{"id":"3242054b9aa4a035","repo":"Pumpkin-MC/Pumpkin","slug":"failed-to-parse-update-response-json-0","errorCode":null,"errorMessage":"Failed to parse update response JSON: {0}","messagePattern":"Failed to parse update response JSON: (.+?)","errorType":"exception","errorClass":"UpdateError","httpStatus":null,"severity":"warning","filePath":"crates/pumpkin-plugin-utils/src/updater.rs","lineNumber":22,"sourceCode":"    http::{HttpClient, HttpError},\n    models::CheckUpdateResponse,\n};\nuse thiserror::Error;\nuse tracing::debug;\n\n/// Update checking errors.\n#[derive(Debug, Error)]\npub enum UpdateError {\n    /// Plugin has not been initialized.\n    #[error(\n        \"Plugin-utils has not been initialized (call pumpkin_plugin_utils::init(context) first)\"\n    )]\n    NotInitialized,\n    /// HTTP error when querying update endpoint.\n    #[error(\"Failed to query update API: {0}\")]\n    Http(#[from] HttpError),\n    /// JSON parsing error from response.\n    #[error(\"Failed to parse update response JSON: {0}\")]\n    Json(#[from] serde_json::Error),\n}\n\n/// Checks for plugin updates against the Pumpkin Marketplace API.\npub struct UpdateChecker {\n    http_client: HttpClient,\n}\n\nimpl Default for UpdateChecker {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\nimpl UpdateChecker {\n    /// Creates a new `UpdateChecker`.\n    #[must_use]\n    pub fn new() -> Self {","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/Pumpkin-MC/Pumpkin/blob/8d4639e25a57c15e47448ec327c780d41bbf2356/crates/pumpkin-plugin-utils/src/updater.rs#L4-L40","documentation":"UpdateError::Json wraps a serde_json::Error produced when the Marketplace API response body cannot be parsed into the expected update-info struct. The library throws it after a successful HTTP call whose payload is not valid JSON or doesn't match the expected schema.","triggerScenarios":"UpdateChecker::check receives a 200 response whose body fails serde deserialization: malformed JSON, HTML error page instead of JSON, or schema drift in the Marketplace API.","commonSituations":"A reverse proxy or captive portal returns an HTML page; Marketplace API version changed its response shape; CDN returns an error document with 200 status.","solutions":["Log the raw response body to see what was actually returned and compare against the expected schema.","Retry the check — transient CDN/proxy pages often resolve on retry.","Update pumpkin-plugin-utils to a version matching the current Marketplace API schema.","Guard the call so a parse failure only disables update notifications rather than the plugin."],"exampleFix":"// before\nlet info = serde_json::from_str::<UpdateInfo>(&body).unwrap();\n// after\nlet info = match update_checker.check() {\n    Ok(i) => i,\n    Err(UpdateError::Json(e)) => { log::warn!(\"bad update payload: {e}\"); return; }\n    Err(e) => { log::warn!(\"update check failed: {e}\"); return; }\n};","handlingStrategy":"fallback","validationCode":"// quick sanity check before trusting the payload\nif !body.trim_start().starts_with('{') {\n    log::warn!(\"update API returned non-JSON body\");\n}","typeGuard":null,"tryCatchPattern":"match update_checker.check() {\n    Ok(info) => info,\n    Err(UpdateError::Json(e)) => { log::warn!(\"unparsable update payload: {e}\"); return; }\n    Err(e) => { log::warn!(\"update check failed: {e}\"); return; }\n}","preventionTips":["Keep pumpkin-plugin-utils updated against Marketplace API schema changes.","Log raw response bodies on parse failure for diagnosis.","Treat update info as optional metadata, never as a hard dependency."],"tags":["json","deserialization","plugin-updates"],"backgroundTag":"json-decode-failed","analyzedSha":"8d4639e25a57c15e47448ec327c780d41bbf2356","analyzedAt":"2026-09-09T15:32:22.916Z","contentChangedAt":"2026-09-09T15:32:22.916Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}