{"record":{"id":"6c1f1b06877cf3d9","repo":"Pumpkin-MC/Pumpkin","slug":"plugin-utils-has-not-been-initialized-call-pumpki-6c1f1b","errorCode":null,"errorMessage":"Plugin-utils has not been initialized (call pumpkin_plugin_utils::init(context) first)","messagePattern":"Plugin-utils has not been initialized \\(call pumpkin_plugin_utils::init\\(context\\) first\\)","errorType":"exception","errorClass":"UpdateError","httpStatus":null,"severity":"error","filePath":"crates/pumpkin-plugin-utils/src/updater.rs","lineNumber":14,"sourceCode":"//! Non-blocking update checks against the marketplace `/api/v1/rest/check-update` endpoint.\n\nuse crate::{\n    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 {","sourceCodeStart":1,"sourceCodeEnd":32,"githubUrl":"https://github.com/Pumpkin-MC/Pumpkin/blob/8d4639e25a57c15e47448ec327c780d41bbf2356/crates/pumpkin-plugin-utils/src/updater.rs#L1-L32","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nfn on_load() {\n    std::thread::spawn(|| check_for_update().ok()); // before init\n}\n// after\nfn on_enable(ctx: &Context) -> Result<()> {\n    pumpkin_plugin_utils::init(ctx)?;\n    std::thread::spawn(|| check_for_update().ok());\n    Ok(())\n}","handlingStrategy":"try-catch","validationCode":"// Guard update checks behind an init flag\nstatic INITED: AtomicBool = AtomicBool::new(false);\nfn check_updates_safe() -> Option<UpdateInfo> {\n    if !INITED.load(Ordering::Acquire) {\n        tracing::warn!(\"skipping update check: plugin-utils not initialized\");\n        return None;\n    }\n    check_for_update().ok()\n}","typeGuard":"fn is_not_initialized(e: &UpdateError) -> bool {\n    matches!(e, UpdateError::NotInitialized)\n}","tryCatchPattern":"match check_for_update() {\n    Err(UpdateError::NotInitialized) => {\n        tracing::error!(\"call pumpkin_plugin_utils::init(ctx) before update checks\");\n        None\n    }\n    other => other.ok(),\n}","preventionTips":["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."],"tags":["initialization","lifecycle","updater","rust"],"backgroundTag":"module-init-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"}