Bug Description
When users explicitly set at_hour or idle_minutes to null in their config.yaml, the SessionResetPolicy.from_dict() method fails to apply default values, resulting in None being passed to validation logic. This causes a TypeError when comparing None with integers.
The issue stems from Python's dict.get() behavior: it only returns the default value when a key is missing, not when the key exists but has a null value.
Steps to Reproduce
- Open your
~/.hermes/config.yaml file
- Modify the
default_reset_policy section to include explicit null values:
default_reset_policy:
mode: both
at_hour: null
idle_minutes: null
-
Restart the Hermes Gateway:
hermes gateway restart
# OR
launchctl stop ai.hermes.gateway && launchctl load ~/Library/LaunchAgents/ai.hermes.gateway.plist
-
Check the gateway logs:
tail -f ~/.hermes/logs/gateway.log
Expected Behavior
The gateway should:
- Accept
null values in the configuration
- Apply default values (
at_hour: 4, idle_minutes: 1440) when null is specified
- Start successfully without errors
- Use the default reset policy values
Actual Behavior
The gateway:
- Accepts
null values but does not apply defaults
- Sets
policy.at_hour and policy.idle_minutes to None
- Fails during validation with
TypeError when checking 0 <= policy.at_hour <= 23
- May crash or behave unpredictably
- Logs errors in the gateway log file
Affected Component
Gateway (Telegram/Discord/Slack/WhatsApp)
Messaging Platform (if gateway-related)
Telegram
Operating System
macOS 14.5
Python Version
3.11.13
Hermes Version
0.20
Relevant Logs / Traceback
Traceback (most recent call last):
File "/Users/chrisqian/Development/hermes-agent/.venv/bin/hermes", line 10, in <module>
sys.exit(main())
^^^^^^
File "/Users/chrisqian/Development/hermes-agent/hermes_cli/main.py", line 2647, in main
args.func(args)
File "/Users/chrisqian/Development/hermes-agent/hermes_cli/main.py", line 508, in cmd_gateway
gateway_command(args)
File "/Users/chrisqian/Development/hermes-agent/hermes_cli/gateway.py", line 960, in gateway_command
run_gateway(verbose, replace=replace)
File "/Users/chrisqian/Development/hermes-agent/hermes_cli/gateway.py", line 417, in run_gateway
success = asyncio.run(start_gateway(replace=replace))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/chrisqian/Library/Application Support/uv/python/cpython-3.11.13-macos-x86_64-none/lib/python3.11/asyncio/runners.py", line 190, in run
return runner.run(main)
^^^^^^^^^^^^^^^^
File "/Users/chrisqian/Library/Application Support/uv/python/cpython-3.11.13-macos-x86_64-none/lib/python3.11/asyncio/runners.py", line 118, in run
return self._loop.run_until_complete(task)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/chrisqian/Library/Application Support/uv/python/cpython-3.11.13-macos-x86_64-none/lib/python3.11/asyncio/base_events.py", line 654, in run_until_complete
return future.result()
^^^^^^^^^^^^^^^
File "/Users/chrisqian/Development/hermes-agent/gateway/run.py", line 3536, in start_gateway
runner = GatewayRunner(config)
^^^^^^^^^^^^^^^^^^^^^
File "/Users/chrisqian/Development/hermes-agent/gateway/run.py", line 223, in __init__
self.config = config or load_gateway_config()
^^^^^^^^^^^^^^^^^^^^^
File "/Users/chrisqian/Development/hermes-agent/gateway/config.py", line 316, in load_gateway_config
if not (0 <= policy.at_hour <= 23):
^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: '<=' not supported between instances of 'int' and 'NoneType'
Root Cause Analysis (optional)
No response
Proposed Fix (optional)
Update SessionResetPolicy.from_dict() to explicitly handle null values:
@classmethod
def from_dict(cls, data: Dict[str, Any]) -> "SessionResetPolicy":
"""
Create SessionResetPolicy from dictionary configuration.
Handles both missing keys and explicit null values correctly.
"""
# Handle None values explicitly — data.get() returns None if key exists with null value
at_hour = data.get("at_hour")
if at_hour is None:
at_hour = 4
idle_minutes = data.get("idle_minutes")
if idle_minutes is None:
idle_minutes = 1440
return cls(
mode=data.get("mode", "both"),
at_hour=at_hour,
idle_minutes=idle_minutes,
)
Are you willing to submit a PR for this?
Bug Description
When users explicitly set
at_houroridle_minutestonullin theirconfig.yaml, theSessionResetPolicy.from_dict()method fails to apply default values, resulting inNonebeing passed to validation logic. This causes aTypeErrorwhen comparingNonewith integers.The issue stems from Python's
dict.get()behavior: it only returns the default value when a key is missing, not when the key exists but has anullvalue.Steps to Reproduce
~/.hermes/config.yamlfiledefault_reset_policysection to include explicitnullvalues:Restart the Hermes Gateway:
Check the gateway logs:
tail -f ~/.hermes/logs/gateway.logExpected Behavior
The gateway should:
nullvalues in the configurationat_hour: 4,idle_minutes: 1440) whennullis specifiedActual Behavior
The gateway:
nullvalues but does not apply defaultspolicy.at_hourandpolicy.idle_minutestoNoneTypeErrorwhen checking0 <= policy.at_hour <= 23Affected Component
Gateway (Telegram/Discord/Slack/WhatsApp)
Messaging Platform (if gateway-related)
Telegram
Operating System
macOS 14.5
Python Version
3.11.13
Hermes Version
0.20
Relevant Logs / Traceback
Root Cause Analysis (optional)
No response
Proposed Fix (optional)
Update
SessionResetPolicy.from_dict()to explicitly handlenullvalues:Are you willing to submit a PR for this?