How I Stopped an AI Agent from Freezing with Two Lines of Code
DEV Community

How I Stopped an AI Agent from Freezing with Two Lines of Code

Have you ever asked someone a question and they just stared at you blankly? It is awkward for humans, but for software, it can cause a complete crash.

I recently contributed a bug fix to the Hermes Agent project. It is an open source AI system that you can run on your own computers. My goal was simple: I wanted to make its permission system much more reliable. Here is a breakdown of the bug I caught, how I fixed it, and why handling empty responses is a big deal in software development.

The Danger of Getting Nothing Back

When you run an AI agent like Hermes, it often needs to ask for permission before running a command on your machine. It does this by sending a request to an approval system. Usually, the system replies with a clear approve or deny. But sometimes things go wrong in the communication pipeline. The system might get absolutely no response at all.

In Python, this blank stare is represented by a special value called None. The old code did not know how to handle None. If it received this unexpected blank response, it would fail silently or cause the entire agent to crash. When you are dealing with AI agents that handle sensitive operations, unpredictable behavior is the last thing you want.

My Fix Using Defensive Coding

The fix was small but very effective. I added a simple check to ensure that if the permission system receives a None response, it safely defaults to denying the request. By adding this tiny safety net, the agent now has a reliable fallback. It prevents crashes and guarantees that users will never have their commands left hanging. Every edge case handled well means fewer surprises when your code is running in the real world.

The Code

Here is the exact change I made in the main file acp_adapter/permissions.py. It is a classic guard clause:

if response is None:
    return "deny"

To make sure this edge case is protected against future changes, I also added a test in tests/acp/test_permissions.py.

You can find the full merged pull request and repository here:

  • fix(permissions): handle None response from ACP request_permission #13457 - aniruddhaadak80 posted on Apr 21, 2026

What does this PR do?

This PR hardens the ACP โ†’ Hermes permission-approval bridge by safely handling an unexpected None result from request_permission, preventing attribute errors and defaulting to a safe deny.

Related Issue

Fixes #13449

Type of Change

  • [x] ๐Ÿ› Bug fix (non-breaking change that fixes an issue)
  • [ ] โœจ New feature (non-breaking change that adds functionality)
  • [ ] ๐Ÿ”’ Security fix
  • [ ] ๐Ÿ“– Documentation update
  • [x] ๐Ÿงช Tests (adding or improving test coverage)
  • [ ] โ™ป๏ธ Refactor (no behavior change)
  • [ ] ๐Ÿ› ๏ธ New skill (bundled or hub)

Changes Made

  • Return "deny" when request_permission resolves to None in the approval callback.
  • Add a unit test covering the None response case to ensure the callback denies safely.

How to Test

  • Connect via an ACP client that sends an empty response to permission requests.
  • Verify the permission is denied rather than throwing an exception.

Checklist

Code

  • [x] I've read the Contributing Guide
  • [x] My commit messages follow Conventional Commits
  • [x] I searched for existing PRs to make sure this isn't a duplicate
  • [x] My PR contains only changes related to this fix/feature (no unrelated commits)
  • [x] I've run pytest tests/ -q and all tests pass
  • [x] I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • [x] I've tested on my platform

Documentation & Housekeeping

  • [x] I've updated relevant documentation (README, docs/, docstrings) โœ… or N/A
  • [x] I've updated cli-config.yaml.example if I added/changed config keys โœ… or N/A
  • [x] I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows โœ… or N/A
  • [x] I've considered cross-platform impact (Windows, macOS) per the compatibility guide โœ… or N/A
  • [x] I've updated tool descriptions/schemas if I changed tool behavior โœ… or N/A

View on GitHub

NousResearch / hermes-agent - The agent that grows with you

Hermes Agent โ˜ค | Hermes Desktop

The self-improving AI agent built by Nous Research. It's the only agent with a built-in learning loop - it creates skills from experience, improves them during use, nudges itself to persist knowledge, searches its own past conversations, and builds a deepening model of who you are across sessions.

Run it on a $5 VPS, a GPU cluster, or serverless infrastructure that costs nearly nothing when idle. It's not tied to your laptop - talk to it from Telegram while it works on a cloud VM. Use any model you want - Nous Portal, OpenRouter, OpenAI, your own endpoint, and many others. Switch with hermes model - no code changes, no lock-in.

  • A real terminal interface - Full TUI with multiline editing, slash-command autocomplete, conversation history, interrupt-and-redirect, and streaming tool output.
  • Lives where you do - Telegram, Discord, Slack, WhatsApp, Signal, and โ€ฆ

How It Works Behind the Scenes

For those curious about the technical side, Hermes handles permission requests using background tasks. When a command needs approval, the agent pauses and waits for the handler to reply. In my updated code, if that background task finishes but spits out a None response, the function intercepts it. It immediately returns deny. It is a simple approach, but it works perfectly. Even in unusual network situations where the system drops the connection, the callback function gives a safe result. The AI agent just keeps on running safely.

My Tech Stack for this Fix

To pull this off, I worked heavily within the Python ecosystem. I used the standard asyncio library to manage the background permission requests. For testing, I used pytest along with mock objects. By mocking the background task to artificially return None, I could prove that the code correctly outputs deny. This allowed me to test the fix without needing to start up the entire heavy infrastructure.

Lessons Learned

Diving into this fix reinforced a few critical rules about building reliable AI systems:

  1. Edge cases matter. In any system that handles user permissions, every single unexpected input needs a clear handling path. Crashing is simply never the right answer.
  2. Testing the weird stuff is vital. It is just as important as testing the paths where everything works perfectly. My regression test ensures this specific behavior will not accidentally break as the code grows.
  3. Open source is highly collaborative. The Hermes community is incredibly welcoming. The team uses AI tools for code review, which is a fantastic way to catch potential improvements early on.

I am glad to have contributed to an open source project that gives developers real control over their own AI agents. Tackling challenges like this is a great way to understand how these systems operate under the hood.

Thanks for reading. If you want to explore AI agents or make your own contributions, check out the Hermes Agent repository.

Comments

No comments yet. Start the discussion.