{"record":{"id":"8f9b93b73b1cb46a","repo":"Pumpkin-MC/Pumpkin","slug":"no-changes","errorCode":null,"errorMessage":"No changes","messagePattern":"No changes","errorType":"error_code","errorClass":"BossbarUpdateError","httpStatus":null,"severity":"info","filePath":"crates/pumpkin/src/world/custom_bossbar.rs","lineNumber":14,"sourceCode":"use crate::entity::player::Player;\nuse crate::server::Server;\nuse crate::world::bossbar::{Bossbar, BossbarColor, BossbarDivisions};\nuse pumpkin_util::text::TextComponent;\nuse rustc_hash::FxHashMap;\nuse std::sync::Arc;\nuse thiserror::Error;\nuse uuid::Uuid;\n\n#[derive(Debug, Error)]\npub enum BossbarUpdateError {\n    #[error(\"Invalid resource location\")]\n    InvalidResourceLocation(String),\n    #[error(\"No changes\")]\n    NoChanges(&'static str, Option<&'static str>),\n}\n\n/// Representing the stored custom boss bars from level.dat\n#[derive(Clone)]\npub struct CustomBossbar {\n    pub namespace: String,\n    pub bossbar_data: Bossbar,\n    pub max: i32,\n    pub value: i32,\n    pub visible: bool,\n    pub players: Vec<Uuid>,\n}\n\nimpl CustomBossbar {\n    #[deny(clippy::new_without_default)]\n    #[must_use]\n    pub const fn new(namespace: String, bossbar_data: Bossbar) -> Self {","sourceCodeStart":1,"sourceCodeEnd":32,"githubUrl":"https://github.com/Pumpkin-MC/Pumpkin/blob/8d4639e25a57c15e47448ec327c780d41bbf2356/crates/pumpkin/src/world/custom_bossbar.rs#L1-L32","documentation":"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).","triggerScenarios":"Calling a bossbar update API (e.g. setting name/color/value/style) with values identical to the currently stored CustomBossbar entry.","commonSituations":"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.","solutions":["Treat this as a benign no-op — catch it and continue instead of treating it as failure","Compute and compare the desired state against current state before calling the update API","Only send fields that actually changed in the update request"],"exampleFix":"// before\nbossbar.update(new_state).map_err(|e| bail!(e))?; // errors on identical state\n// after\nif let Err(BossbarUpdateError::NoChanges(..)) = bossbar.update(new_state) { /* no-op, ok */ }","handlingStrategy":"try-catch","validationCode":"if current_state == new_state { return; /* nothing to do, skip the update call */ }","typeGuard":null,"tryCatchPattern":"match bossbar.update(new_state) {\n    Err(BossbarUpdateError::NoChanges(a, b)) => log::debug!(\"no-op update: {a} {b:?}\"),\n    Ok(()) => { /* proceed */ }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Diff desired vs. stored state before invoking the update API","Treat NoChanges as success in idempotent config-apply loops","Avoid re-sending identical updates every tick; cache last-applied state"],"tags":["rust","minecraft","bossbar","idempotency"],"backgroundTag":"no-op-update","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"}