Once ban_hammer() in modules/system.py creates a new seenNodes entry, every subsequent DM to the bot fails with KeyError: 'nodeID', regardless of message content. The bot logs the DM as ignored and never processes it as a command.
Root Cause
ban_hammer() (modules/system.py, around line 1147) builds new seenNodes entries with the key node_id:
Everywhere else that populates or reads seenNodes (mesh_bot.py, e.g. line 2124) uses the key nodeID instead. Once a node_id-keyed entry lands in the shared global list, this check in mesh_bot.py (line 2284) throws on it:
any() walks the entire seenNodes list, so the crash isn't limited to the node ban_hammer flagged. It breaks the welcome check for every node's DM from that point forward, until the service restarts and the in-memory list clears. seenNodes isn't persisted to disk, so a restart is a temporary workaround, not a fix.
The same unguarded node['nodeID'] pattern also appears at lines 701, 1832, and 2289, all vulnerable to the same issue. Line 2123 already uses node.get('nodeID') defensively, so the fix pattern already exists in the codebase, it's just not applied consistently.
Steps to Reproduce
Trigger ban_hammer() for any node (repeated messages within the auto-ban timeframe/threshold).
From a different node, send any DM to the bot.
Bot logs Ignoring DM and the traceback below, and every DM from any node fails identically until restart.
Log Output
WARNING | Ignoring DM: <message> From: <node>
ERROR | System: Error processing packet: 'nodeID'
Traceback (most recent call last):
File "mesh_bot.py", line 2284, in onReceive
if not any(node['nodeID'] == message_from_id and node['welcome'] == True for node in seenNodes):
File "mesh_bot.py", line 2284, in <genexpr>
if not any(node['nodeID'] == message_from_id and node['welcome'] == True for node in seenNodes):
KeyError: 'nodeID'
Suggested Fix
Either:
Change modules/system.py line ~1147 from 'node_id': node_id_str to 'nodeID': node_id_str, matching the schema used everywhere else, or
Change the direct node['nodeID'] accesses in mesh_bot.py (lines 701, 1832, 2284, 2289) to node.get('nodeID'), so one malformed entry can't take down the whole check.
Option 1 fixes the root cause. Option 2 is defensive and worth doing regardless, since two schemas sharing one global list is a repeat risk.
Environment
meshing-around version/commit: 2.0.0
Install method: venv
## Description
Once `ban_hammer()` in `modules/system.py` creates a new `seenNodes` entry, every subsequent DM to the bot fails with `KeyError: 'nodeID'`, regardless of message content. The bot logs the DM as ignored and never processes it as a command.
## Root Cause
`ban_hammer()` (modules/system.py, around line 1147) builds new `seenNodes` entries with the key `node_id`:
```python
entry = {
'node_id': node_id_str,
'first_seen': current_time,
'lastSeen': current_time,
'auto_ban_count': 3,
'rxInterface': rxInterface,
'channel': channel,
'welcome': False
}
seenNodes.append(entry)
```
Everywhere else that populates or reads `seenNodes` (mesh_bot.py, e.g. line 2124) uses the key `nodeID` instead. Once a `node_id`-keyed entry lands in the shared global list, this check in mesh_bot.py (line 2284) throws on it:
```python
if not any(node['nodeID'] == message_from_id and node['welcome'] == True for node in seenNodes):
```
`any()` walks the entire `seenNodes` list, so the crash isn't limited to the node `ban_hammer` flagged. It breaks the welcome check for every node's DM from that point forward, until the service restarts and the in-memory list clears. `seenNodes` isn't persisted to disk, so a restart is a temporary workaround, not a fix.
The same unguarded `node['nodeID']` pattern also appears at lines 701, 1832, and 2289, all vulnerable to the same issue. Line 2123 already uses `node.get('nodeID')` defensively, so the fix pattern already exists in the codebase, it's just not applied consistently.
## Steps to Reproduce
1. Trigger `ban_hammer()` for any node (repeated messages within the auto-ban timeframe/threshold).
2. From a different node, send any DM to the bot.
3. Bot logs `Ignoring DM` and the traceback below, and every DM from any node fails identically until restart.
## Log Output
```
WARNING | Ignoring DM: <message> From: <node>
ERROR | System: Error processing packet: 'nodeID'
Traceback (most recent call last):
File "mesh_bot.py", line 2284, in onReceive
if not any(node['nodeID'] == message_from_id and node['welcome'] == True for node in seenNodes):
File "mesh_bot.py", line 2284, in <genexpr>
if not any(node['nodeID'] == message_from_id and node['welcome'] == True for node in seenNodes):
KeyError: 'nodeID'
```
## Suggested Fix
Either:
1. Change `modules/system.py` line ~1147 from `'node_id': node_id_str` to `'nodeID': node_id_str`, matching the schema used everywhere else, or
2. Change the direct `node['nodeID']` accesses in mesh_bot.py (lines 701, 1832, 2284, 2289) to `node.get('nodeID')`, so one malformed entry can't take down the whole check.
Option 1 fixes the root cause. Option 2 is defensive and worth doing regardless, since two schemas sharing one global list is a repeat risk.
## Environment
- meshing-around version/commit: 2.0.0
- Install method: venv
<!-- github-sync-id:5538382513 -->
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Description
Once
ban_hammer()inmodules/system.pycreates a newseenNodesentry, every subsequent DM to the bot fails withKeyError: 'nodeID', regardless of message content. The bot logs the DM as ignored and never processes it as a command.Root Cause
ban_hammer()(modules/system.py, around line 1147) builds newseenNodesentries with the keynode_id:Everywhere else that populates or reads
seenNodes(mesh_bot.py, e.g. line 2124) uses the keynodeIDinstead. Once anode_id-keyed entry lands in the shared global list, this check in mesh_bot.py (line 2284) throws on it:any()walks the entireseenNodeslist, so the crash isn't limited to the nodeban_hammerflagged. It breaks the welcome check for every node's DM from that point forward, until the service restarts and the in-memory list clears.seenNodesisn't persisted to disk, so a restart is a temporary workaround, not a fix.The same unguarded
node['nodeID']pattern also appears at lines 701, 1832, and 2289, all vulnerable to the same issue. Line 2123 already usesnode.get('nodeID')defensively, so the fix pattern already exists in the codebase, it's just not applied consistently.Steps to Reproduce
ban_hammer()for any node (repeated messages within the auto-ban timeframe/threshold).Ignoring DMand the traceback below, and every DM from any node fails identically until restart.Log Output
Suggested Fix
Either:
modules/system.pyline ~1147 from'node_id': node_id_strto'nodeID': node_id_str, matching the schema used everywhere else, ornode['nodeID']accesses in mesh_bot.py (lines 701, 1832, 2284, 2289) tonode.get('nodeID'), so one malformed entry can't take down the whole check.Option 1 fixes the root cause. Option 2 is defensive and worth doing regardless, since two schemas sharing one global list is a repeat risk.
Environment
this may resolve the issue?
Ok I just did the update. So far promising.
Thanks for catching it, typo on my end.