{"record":{"id":"f979bd638e327825","repo":"Pumpkin-MC/Pumpkin","slug":"json-serialization-error-0","errorCode":null,"errorMessage":"JSON serialization error: {0}","messagePattern":"JSON serialization error: (.+?)","errorType":"exception","errorClass":"LicenseError","httpStatus":null,"severity":"error","filePath":"crates/pumpkin-plugin-utils/src/license.rs","lineNumber":33,"sourceCode":"#[derive(Debug, Error)]\npub enum LicenseError {\n    /// HTTP communication error with marketplace.\n    #[error(\"Marketplace HTTP error: {0}\")]\n    Http(#[from] HttpError),\n    /// Metadata validation error (e.g. missing license on paid plugin).\n    #[error(\"License metadata mismatch: {0}\")]\n    MetadataMismatch(String),\n    /// License revoked or refunded by marketplace.\n    #[error(\"License was revoked or refunded: {0}\")]\n    Revoked(String),\n    /// License is expired.\n    #[error(\"License has expired on {0}\")]\n    Expired(String),\n    /// I/O error reading/writing license cache.\n    #[error(\"I/O error with license storage: {0}\")]\n    Io(#[from] std::io::Error),\n    /// JSON serialization error.\n    #[error(\"JSON serialization error: {0}\")]\n    Json(#[from] serde_json::Error),\n    /// Plugin is unsigned or missing marketplace metadata.\n    #[error(\"Plugin is unsigned or missing marketplace metadata\")]\n    UnsignedPlugin,\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}\n\n/// Manages license checks, cached leases, and offline grace periods.\npub struct LicenseChecker {\n    data_folder: PathBuf,\n    http_client: HttpClient,\n}\n\nimpl LicenseChecker {","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/Pumpkin-MC/Pumpkin/blob/8d4639e25a57c15e47448ec327c780d41bbf2356/crates/pumpkin-plugin-utils/src/license.rs#L15-L51","documentation":"LicenseError::Json wraps serde_json::Error (#[from]) from serializing or deserializing license data — chiefly the cached lease file on disk, or parsing marketplace JSON payloads. A malformed or corrupted cache file is the most common source. The serde error detail is embedded via {0}.","triggerScenarios":"Deserializing the license cache file whose JSON no longer matches the current struct schema (library upgrade changed fields), or the file was truncated/hand-edited; also serializing the lease before writing, or decoding an unexpected marketplace API response body.","commonSituations":"Upgrading the plugin (or plugin-utils) after the lease struct changed, leaving an incompatible cache; partially written cache from a crash; manual edits to the cache file; marketplace API response shape changed.","solutions":["Delete the license cache file and re-verify online to write a fresh lease.","Match the plugin-utils version to the one that wrote the cache (schema drift after upgrades).","If the error names a marketplace response, check for marketplace API changes and update plugin-utils.","Restore the cache from backup or let the library regenerate it (requires connectivity).","Inspect {0} — 'missing field'/'invalid type' point at schema mismatch; 'EOF while parsing' at truncation."],"exampleFix":"// before\nlet lease: LicenseLease = serde_json::from_str(&cache)?; // schema drift\n// after\nlet lease = match serde_json::from_str::<LicenseLease>(&cache) {\n    Ok(l) => l,\n    Err(e) => {\n        tracing::warn!(\"license cache unusable ({e}); re-verifying online\");\n        std::fs::remove_file(&cache_path).ok();\n        manager.verify_online()?\n    }\n};","handlingStrategy":"fallback","validationCode":"// Sanity-check the cache file parses before handing it to the manager\nif let Ok(raw) = std::fs::read_to_string(&cache_path) {\n    if serde_json::from_str::<serde_json::Value>(&raw).is_err() {\n        tracing::warn!(\"license cache corrupt; deleting before verify\");\n        let _ = std::fs::remove_file(&cache_path);\n    }\n}","typeGuard":"fn is_json_error(e: &LicenseError) -> bool {\n    matches!(e, LicenseError::Json(_))\n}","tryCatchPattern":"match manager.verify() {\n    Err(LicenseError::Json(e)) => {\n        tracing::warn!(\"cache schema mismatch ({e}); re-verifying online\");\n        let _ = std::fs::remove_file(&cache_path);\n        manager.verify_online()\n    }\n    other => other,\n}","preventionTips":["Upgrade plugin-utils and the plugin together to avoid cache schema drift.","Never hand-edit the license cache file.","Delete the cache rather than repairing it after crashes.","Pin marketplace API expectations to the plugin-utils version in use."],"tags":["json","serde","license-cache","rust"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"8d4639e25a57c15e47448ec327c780d41bbf2356","analyzedAt":"2026-09-09T15:32:22.916Z","contentChangedAt":"2026-09-09T15:32:22.916Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}