IRC bot crashes on inbound message due to wrong `BotMessage` field names
IRC bot crashes on inbound message due to wrong BotMessage field names
Repository: MervinPraison/PraisonAI
Component: praisonai-bot IRC adapter
Labels: bug, irc, priority:high
Platform observed: Windows 11, Python 3.13
Summary
The IRC bot adapter crashes when processing the first inbound channel message because it constructs BotMessage with keyword arguments text and user, but the shared message model expects content and sender. The bot connects to IRC successfully, joins the channel, but dies on the first Hi message.
Discovered during live IRC test on Libera.Chat channel ##praison-test. Fix: use correct field names in praisonai_bot/bots/irc.py.
Environment
| Item | Value |
|---|---|
| OS | Windows 11 |
| Python | 3.13.2 |
| IRC server | irc.libera.chat |
| Channel | ##praison-test |
| Nickname | praison-ai-bot |
| Config | irc-bot.yaml via praisonai bot start |
Steps to reproduce
1. Configure IRC bot
platform: irc
server: "${IRC_SERVER}"
channel: "${IRC_CHANNEL}"
nickname: "${IRC_NICKNAME}"
agent:
name: "IRC Assistant"
instructions: "Reply briefly."
llm: "gpt-4o-mini"2. Set environment and start
$env:OPENAI_API_KEY = "sk-..."
$env:IRC_SERVER = "irc.libera.chat"
$env:IRC_CHANNEL = "##praison-test"
$env:IRC_NICKNAME = "praison-ai-bot"
praisonai bot start --config irc-bot.yaml3. Join channel and send Hi
From another IRC client:
/join ##praison-test
HiTerminal evidence (crash on first message)
[INFO] Connecting to irc.libera.chat:6667
[INFO] IRC nick: praison-ai-bot
[INFO] Joining ##praison-test
[INFO] Connected and listening
Traceback (most recent call last):
File "praisonai_bot/bots/irc.py", line 142, in _on_pubmsg
msg = BotMessage(
^^^^^^^^^^^
TypeError: BotMessage.__init__() got an unexpected keyword argument 'text'Process exits or enters broken state. No reply sent to channel.
Alternative traceback observed in some versions:
TypeError: BotMessage.__init__() got an unexpected keyword argument 'user'Terminal evidence (after fix)
Patch IRC adapter to use:
BotMessage(content=text, sender=nick, ...)Restart bot:
praisonai bot start --config irc-bot.yaml[INFO] Connecting to irc.libera.chat:6667
[INFO] Joined ##praison-test
[INFO] Received PRIVMSG from testuser: Hi
[INFO] Routing to agent IRC Assistant
[INFO] LLM response (912ms)
[INFO] Sending PRIVMSG to ##praison-testIRC channel shows:
<testuser> Hi
<praison-ai-bot> Hello! How can I assist you today?Live audit result: PASS (~2s after fix).
Root cause
IRC adapter was written against an outdated or assumed BotMessage signature:
# Broken
BotMessage(text=message_body, user=nickname, channel=chan)
# Correct (shared model)
BotMessage(content=message_body, sender=nickname, channel=chan)Other adapters (Telegram, Slack) already use content/sender. IRC was inconsistent.
Expected vs actual
| Event | Expected | Actual (before fix) |
|---|---|---|
| Connect to IRC | Success | Success |
| Join channel | Success | Success |
| Receive Hi | Agent reply in channel | TypeError crash |
| Process stays up | Yes | No |
Impact
| Area | Effect |
|---|---|
| IRC channel onboarding | 100% fail at first message |
| Channel expansion roadmap | IRC marked implemented but unusable |
| Unit tests | 7/7 IRC unit tests passed — integration field mismatch not caught |
| User trust | "IRC support exists" but crashes live |
Why unit tests missed it
Unit tests may mock BotMessage or test connection/join in isolation without asserting constructor kwargs against real dataclass signature.
Recommended addition:
def test_irc_on_pubmsg_builds_valid_bot_message():
irc_bot._on_pubmsg(connection, event)
assert captured_message.content == "Hi"
assert captured_message.sender == "testuser"Workaround
Patch praisonai_bot/bots/irc.py locally:
# Replace text= with content=
# Replace user= with sender=Reinstall editable package or set PYTHONPATH to patched source.
Proposed upstream fix
- Fix field names in IRC adapter.
- Add integration test with real
BotMessageimport. - Lint rule: grep for
BotMessage(text=across codebase. - Align all platform adapters to shared factory helper:
def make_message(content: str, sender: str, **kwargs) -> BotMessage:
return BotMessage(content=content, sender=sender, **kwargs)Full traceback (representative)
Exception in thread IRCBot-polling:
Traceback (most recent call last):
File "threading.py", line 1041, in _bootstrap_inner
self.run()
File "threading.py", line 992, in run
self._target(*self._args, **self._kwargs)
File "praisonai_bot/bots/irc.py", line 98, in _listen_loop
self._dispatch(event)
File "praisonai_bot/bots/irc.py", line 130, in _dispatch
self._on_pubmsg(conn, event)
File "praisonai_bot/bots/irc.py", line 142, in _on_pubmsg
msg = BotMessage(
text=event.arguments[0],
user=event.source.nick,
channel=event.target,
platform="irc",
)
TypeError: BotMessage.__init__() got an unexpected keyword argument 'text'BotMessage signature (reference)
@dataclass
class BotMessage:
content: str
sender: str
channel: str | None = None
platform: str = ""
metadata: dict = field(default_factory=dict)Any adapter using text or user will fail at runtime.
IRC-specific connection log (successful connect, failed handle)
*** Looking up irc.libera.chat
*** Connecting to irc.libera.chat (6667)
*** Connection established
*** Registering nick praison-ai-bot
*** Joining ##praison-test
*** praison-ai-bot joined ##praison-testThen user message triggers crash — channel sees bot join then go quiet.
Verification checklist
- IRC bot survives first PRIVMSG
- Reply appears in channel within 5s
- No TypeError in logs
- All platform adapters use shared message factory
- Integration test in CI
Severity
High — IRC feature completely non-functional in live use despite passing unit tests and startup checks.
Audit notes
| Metric | Value |
|---|---|
| Steps to IRC first reply | 7 |
| Time to connect | ~5s |
| Time to crash | immediate on first Hi |
| Time to pass after fix | ~2s reply |
Appendix: reproduction one-liner
$env:OPENAI_API_KEY="sk-..."; $env:IRC_SERVER="irc.libera.chat"; $env:IRC_CHANNEL="##praison-test"; $env:IRC_NICKNAME="praison-ai-bot"; praisonai bot start --config irc-bot.yamlSend Hi from second client. Before fix: TypeError. After fix: Hello reply.
IRC wire-level context
:PraisonUser!~user@host PRIVMSG ##praison-test :HiAdapter parses nick PraisonUser, text Hi, target ##praison-test.
Broken mapping:
BotMessage(text="Hi", user="PraisonUser") # TypeErrorCorrect:
BotMessage(content="Hi", sender="PraisonUser", channel="##praison-test", platform="irc")Libera.Chat live test evidence
* praison-ai-bot has joined ##praison-test
<PraisonUser> Hi
(connection lost — bot process died)After fix:
<PraisonUser> Hi
<praison-ai-bot> Hello! How can I assist you today?Join + first message is minimum reproduction — no prior channel activity required.
Source: MervinPraison/PraisonAI