From 39c3a0a6ae8472da66701ef32ce46832108f8a72 Mon Sep 17 00:00:00 2001 From: William Barnhart Date: Sun, 19 Jul 2026 03:50:03 +0000 Subject: [PATCH] Harden reply-topic creation against a hardcoded replicas=0 _reply_topic() (the ephemeral topic backing agent .ask()/reply_to) hardcoded replicas=0. #76 reported this crashing topic creation with InvalidReplicationFactorError on brokers that reject a replication factor of 0 -- most do, via min.insync.replicas. On current code the acute crash no longer reproduces: Topic.declare() already falls back to app.conf.topic_replication_factor whenever `self.replicas` is falsy (`if self.replicas: ... else: ...`), and 0 is falsy in Python, so the hardcoded 0 was already being silently replaced by the configured default (1) before reaching the broker. That's a coincidence of Python truthiness, not an intentional contract -- nothing stops a future change to that fallback (e.g. distinguishing an explicit 0 from an unset value) from reintroducing today's crash. Pass app.conf.topic_replication_factor explicitly instead of the magic 0, consistent with how every other topic faust creates picks up its replication factor. No longer relies on the fallback to mask the wrong value. The existing test_reply_topic asserted the old, wrong value (topic.replicas == 0); updated to assert the topic gets a real, broker-acceptable replication factor. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01HHPL4VFWQRQPpjR1gXSKyL --- faust/agents/replies.py | 2 +- tests/unit/agents/test_replies.py | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/faust/agents/replies.py b/faust/agents/replies.py index b4e4247c8..59233fb29 100644 --- a/faust/agents/replies.py +++ b/faust/agents/replies.py @@ -189,7 +189,7 @@ def _reply_topic(self, topic: str) -> TopicT: return self.app.topic( topic, partitions=1, - replicas=0, + replicas=self.app.conf.topic_replication_factor, deleting=True, retention=self.app.conf.reply_expires, value_type=ReqRepResponse, diff --git a/tests/unit/agents/test_replies.py b/tests/unit/agents/test_replies.py index 36628d9c0..cbc6d0bb9 100644 --- a/tests/unit/agents/test_replies.py +++ b/tests/unit/agents/test_replies.py @@ -254,7 +254,12 @@ def test_reply_topic(self, *, c, app): topic = c._reply_topic("foo") assert topic.get_topic_name() == "foo" assert topic.partitions == 1 - assert topic.replicas == 0 + # Must not hardcode 0: most brokers reject a replication factor of + # 0 outright (InvalidReplicationFactorError, see + # faust-streaming/faust#76). Use the app's configured default + # instead, consistent with every other topic faust creates. + assert topic.replicas == app.conf.topic_replication_factor + assert topic.replicas > 0 assert topic.deleting assert topic.retention == app.conf.reply_expires assert topic.value_type is ReqRepResponse