Pumpkin-MC/Pumpkin · error · UpdateError
Plugin-utils has not been initialized (call…
Error message
Plugin-utils has not been initialized (call pumpkin_plugin_utils::init(context) first)
What it means
UpdateError::NotInitialized from pumpkin-plugin-utils' updater means an update check was requested before pumpkin_plugin_utils::init(context) ran, so the updater lacks the plugin context (id, version, marketplace client) needed to query the update endpoint. Like its license.rs counterpart, it signals a startup-order bug.
Solutions
- Call pumpkin_plugin_utils::init(context) before triggering any update check.
- Schedule update checks after the enabled/loaded hook, not in the constructor.
- Handle init's Result so a failed init is noticed before update checks run.
- If using a background task, spawn it after init completes and pass the initialized context.
- Unit-test startup order so the updater is never invoked pre-init.
Example fix
// before
fn on_load() {
std::thread::spawn(|| check_for_update().ok()); // before init
}
// after
fn on_enable(ctx: &Context) -> Result<()> {
pumpkin_plugin_utils::init(ctx)?;
std::thread::spawn(|| check_for_update().ok());
Ok(())
} Defensive patterns
Strategy: try-catch
Validate before calling
// Guard update checks behind an init flag
static INITED: AtomicBool = AtomicBool::new(false);
fn check_updates_safe() -> Option<UpdateInfo> {
if !INITED.load(Ordering::Acquire) {
tracing::warn!("skipping update check: plugin-utils not initialized");
return None;
}
check_for_update().ok()
} Type guard
fn is_not_initialized(e: &UpdateError) -> bool {
matches!(e, UpdateError::NotInitialized)
} Try / catch
match check_for_update() {
Err(UpdateError::NotInitialized) => {
tracing::error!("call pumpkin_plugin_utils::init(ctx) before update checks");
None
}
other => other.ok(),
} Prevention
- Initialize via pumpkin_plugin_utils::init(context) before spawning update tasks.
- Run update checks from lifecycle hooks, not constructors.
- Check init's Result before scheduling background checks.
- Gate update checks behind an initialized flag in shared state.
When it happens
Trigger: Calling update-check functions (e.g. check_for_update) during plugin construction or before init(context) completed; init skipped; init called with a different context than the updater uses.
Common situations: Checking for updates in the plugin constructor; background update task spawned before initialization finished; init result ignored so the updater silently stayed uninitialized; reordered startup code after a refactor.
Related errors
- Plugin-utils has not been initialized (call…
- Plugin initialization failed
- Failed to load library
- Missing plugin metadata
- Missing plugin entrypoint
AI-assisted analysis of Pumpkin-MC/Pumpkin@8d4639e25a (2026-09-09).
Data as JSON: /api/errors/6c1f1b06877cf3d9.
Report an issue: GitHub.
Appendix: source
Thrown at crates/pumpkin-plugin-utils/src/updater.rs:14
//! Non-blocking update checks against the marketplace `/api/v1/rest/check-update` endpoint.
use crate::{
http::{HttpClient, HttpError},
models::CheckUpdateResponse,
};
use thiserror::Error;
use tracing::debug;
/// Update checking errors.
#[derive(Debug, Error)]
pub enum UpdateError {
/// Plugin has not been initialized.
#[error(
"Plugin-utils has not been initialized (call pumpkin_plugin_utils::init(context) first)"
)]
NotInitialized,
/// HTTP error when querying update endpoint.
#[error("Failed to query update API: {0}")]
Http(#[from] HttpError),
/// JSON parsing error from response.
#[error("Failed to parse update response JSON: {0}")]
Json(#[from] serde_json::Error),
}
/// Checks for plugin updates against the Pumpkin Marketplace API.
pub struct UpdateChecker {
http_client: HttpClient,
}
impl Default for UpdateChecker {
fn default() -> Self {View on GitHub (pinned to 8d4639e25a)