Pumpkin-MC/Pumpkin · info · BossbarUpdateError

No changes

Error message

No changes

What it means

BossbarUpdateError::NoChanges, thrown when a bossbar update operation is invoked but the new state is identical to the stored state, so nothing is written to level.dat. The payload carries two static string fields describing which aspect was compared (and optionally which value).

Solutions

  1. Treat this as a benign no-op — catch it and continue instead of treating it as failure
  2. Compute and compare the desired state against current state before calling the update API
  3. Only send fields that actually changed in the update request

Example fix

// before
bossbar.update(new_state).map_err(|e| bail!(e))?; // errors on identical state
// after
if let Err(BossbarUpdateError::NoChanges(..)) = bossbar.update(new_state) { /* no-op, ok */ }
Defensive patterns

Strategy: try-catch

Validate before calling

if current_state == new_state { return; /* nothing to do, skip the update call */ }

Try / catch

match bossbar.update(new_state) {
    Err(BossbarUpdateError::NoChanges(a, b)) => log::debug!("no-op update: {a} {b:?}"),
    Ok(()) => { /* proceed */ }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Calling a bossbar update API (e.g. setting name/color/value/style) with values identical to the currently stored CustomBossbar entry.

Common situations: Idempotent repeated commands or plugins re-applying the same config every tick; retry logic re-sending an already-applied update; UI sending unchanged form data.

Related errors


AI-assisted analysis of Pumpkin-MC/Pumpkin@8d4639e25a (2026-09-09). Data as JSON: /api/errors/8f9b93b73b1cb46a. Report an issue: GitHub.

Appendix: source

Thrown at crates/pumpkin/src/world/custom_bossbar.rs:14

use crate::entity::player::Player;
use crate::server::Server;
use crate::world::bossbar::{Bossbar, BossbarColor, BossbarDivisions};
use pumpkin_util::text::TextComponent;
use rustc_hash::FxHashMap;
use std::sync::Arc;
use thiserror::Error;
use uuid::Uuid;

#[derive(Debug, Error)]
pub enum BossbarUpdateError {
    #[error("Invalid resource location")]
    InvalidResourceLocation(String),
    #[error("No changes")]
    NoChanges(&'static str, Option<&'static str>),
}

/// Representing the stored custom boss bars from level.dat
#[derive(Clone)]
pub struct CustomBossbar {
    pub namespace: String,
    pub bossbar_data: Bossbar,
    pub max: i32,
    pub value: i32,
    pub visible: bool,
    pub players: Vec<Uuid>,
}

impl CustomBossbar {
    #[deny(clippy::new_without_default)]
    #[must_use]
    pub const fn new(namespace: String, bossbar_data: Bossbar) -> Self {

View on GitHub (pinned to 8d4639e25a)