diff --git a/esphome/components/mqtt/mqtt_client.cpp b/esphome/components/mqtt/mqtt_client.cpp index 0708d371a8d..803f486333a 100644 --- a/esphome/components/mqtt/mqtt_client.cpp +++ b/esphome/components/mqtt/mqtt_client.cpp @@ -491,8 +491,11 @@ void MQTTClientComponent::unsubscribe(const std::string &topic) { subscription.removed = true; } // A callback may be running; the outermost dispatch erases them once it returns. - if (!this->dispatching_) + if (this->dispatching_) { + this->removed_while_dispatching_ = true; + } else { this->erase_removed_subscriptions_(); + } } void MQTTClientComponent::erase_removed_subscriptions_() { @@ -668,8 +671,10 @@ void MQTTClientComponent::on_message(const std::string &topic, const std::string subscription.callback.call(topic, payload); } this->dispatching_ = was_dispatching; - if (!was_dispatching) + if (!was_dispatching && this->removed_while_dispatching_) { + this->removed_while_dispatching_ = false; this->erase_removed_subscriptions_(); + } #ifdef USE_ESP8266 }); #endif diff --git a/esphome/components/mqtt/mqtt_client.h b/esphome/components/mqtt/mqtt_client.h index 50fa706c09d..30edb812975 100644 --- a/esphome/components/mqtt/mqtt_client.h +++ b/esphome/components/mqtt/mqtt_client.h @@ -369,6 +369,7 @@ class MQTTClientComponent final : public Component { bool publish_nan_as_none_{false}; bool wait_for_connection_{false}; bool dispatching_{false}; + bool removed_while_dispatching_{false}; }; extern MQTTClientComponent *global_mqtt_client; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)