Pumpkin-MC/Pumpkin · error · LicenseError
JSON serialization error
Error message
JSON serialization error: {0} What it means
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}.
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.
Example fix
// before
let lease: LicenseLease = serde_json::from_str(&cache)?; // schema drift
// after
let lease = match serde_json::from_str::<LicenseLease>(&cache) {
Ok(l) => l,
Err(e) => {
tracing::warn!("license cache unusable ({e}); re-verifying online");
std::fs::remove_file(&cache_path).ok();
manager.verify_online()?
}
}; Defensive patterns
Strategy: fallback
Validate before calling
// Sanity-check the cache file parses before handing it to the manager
if let Ok(raw) = std::fs::read_to_string(&cache_path) {
if serde_json::from_str::<serde_json::Value>(&raw).is_err() {
tracing::warn!("license cache corrupt; deleting before verify");
let _ = std::fs::remove_file(&cache_path);
}
} Type guard
fn is_json_error(e: &LicenseError) -> bool {
matches!(e, LicenseError::Json(_))
} Try / catch
match manager.verify() {
Err(LicenseError::Json(e)) => {
tracing::warn!("cache schema mismatch ({e}); re-verifying online");
let _ = std::fs::remove_file(&cache_path);
manager.verify_online()
}
other => other,
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
AI-assisted analysis of Pumpkin-MC/Pumpkin@8d4639e25a (2026-09-09).
Data as JSON: /api/errors/f979bd638e327825.
Report an issue: GitHub.
Appendix: source
Thrown at crates/pumpkin-plugin-utils/src/license.rs:33
#[derive(Debug, Error)]
pub enum LicenseError {
/// HTTP communication error with marketplace.
#[error("Marketplace HTTP error: {0}")]
Http(#[from] HttpError),
/// Metadata validation error (e.g. missing license on paid plugin).
#[error("License metadata mismatch: {0}")]
MetadataMismatch(String),
/// License revoked or refunded by marketplace.
#[error("License was revoked or refunded: {0}")]
Revoked(String),
/// License is expired.
#[error("License has expired on {0}")]
Expired(String),
/// I/O error reading/writing license cache.
#[error("I/O error with license storage: {0}")]
Io(#[from] std::io::Error),
/// JSON serialization error.
#[error("JSON serialization error: {0}")]
Json(#[from] serde_json::Error),
/// Plugin is unsigned or missing marketplace metadata.
#[error("Plugin is unsigned or missing marketplace metadata")]
UnsignedPlugin,
/// Plugin has not been initialized.
#[error(
"Plugin-utils has not been initialized (call pumpkin_plugin_utils::init(context) first)"
)]
NotInitialized,
}
/// Manages license checks, cached leases, and offline grace periods.
pub struct LicenseChecker {
data_folder: PathBuf,
http_client: HttpClient,
}
impl LicenseChecker {View on GitHub (pinned to 8d4639e25a)