A tiny missing check, a silent crash, and a denied permission that should have been safe. This is the story of how I fixed it.
I am Aniruddha Adak, a full stack developer from Kolkata, working across Next.js
, React
, TypeScript
, Python
and AI agent tooling
. My GitHub profile is ** aniruddhaadak80** with over
google-gemini/gemini-cli
, openclaw/openclaw
, topoteretes/cognee
and NousResearch/hermes-agent
.Over the last two years I have been focusing on one thing, finding bugs that hide in plain sight, especially those that appear only on edge cases, cross platform setups and agent communication layers.
This post is my submission for DEV Summer Bug Smash 2026 in the Clear the Lineup track. It is also aiming for Best Use of Google AI.
The bug lived in NousResearch/hermes-agent, an open agent framework that connects AI models through the ACP protocol.
Inside the permission bridge, the function request_permission
is expected to return an object that tells Hermes whether to allow or deny an action. But sometimes, when an ACP client sends an empty response, that function returns None
.
The existing code trusted the result directly and accessed result.decision
without checking. When result
is None
, this throws an AttributeError. The agent crashes instead of denying safely. For a permission system, crashing is worse than denying. It leaves the user hanging and can break long running sessions.
In simple words, the code trusted that it would always get an answer. When it got silence, it broke.
I was working through open issues in hermes-agent
while exploring how agent permissions work on different clients. I noticed issue #13449 which described unexpected crashes during permission approval. I traced the flow from agent/transports
to the ACP callback and I saw there was no guard for None
. I reproduced it locally by mocking request_permission
to return None
and the crash happened instantly.
The bug was small, but its impact was large. Permission checks should never throw. They should always fail safe.
To reproduce, you connect via an ACP client that can send an empty response to permission requests. Then you trigger any tool that requires permission approval and you send an empty payload from the client. In the server logs you will see AttributeError: 'NoneType' object has no attribute 'decision'
.
My reproduction script was simple and it showed the problem clearly.
async def mock_request_permission():
return None
result = await mock_request_permission()
decision = result.decision
With the old code, this crashes immediately. With the new code, it safely denies.
My merged PR is fix(permissions): handle None response from ACP request_permission in the hermes-agent repository. The PR link is https://github.com/NousResearch/hermes-agent/pull/13457 and it is merged.
I added a guard clause right after the await
. If the response is None
, I return "deny"
immediately. I added a dedicated unit test for this edge case and I kept the change minimal to avoid touching any other permission logic.
New logic looks like this
result = await request_permission(...)
if result is None:
return "deny"
if result.decision == "allow":
return "allow"
return "deny"
This is a classic fail safe pattern. In security code, when you do not know what happened, you deny. This pattern is simple, it is readable, and it prevents a whole class of crashes.
It does not change the happy path at all. It prevents a crash that could be triggered by any ACP client. It aligns with the principle of least privilege and it adds test coverage so it will not regress in future releases.
I built this fix using Antigravity, the agentic IDE by Google, and it changed how I debug. For codebase exploration I used Gemini 2.5 Pro inside Antigravity to map all places where request_permission
is called and where its return value is used. It gave me a full call graph in seconds and saved hours of manual search.
For reproduction scaffolding I prompted Antigravity to write a minimal async mock that returns None for ACP permission and triggers the approval callback. Antigravity generated the repro script and the test harness. For edge case reasoning I asked Gemini to list what else could be None in that bridge. It suggested checking for missing fields inside the result as a future hardening step.
I treat Antigravity as a pair programmer that never gets tired of reading large repos. It reads the whole codebase, I make the final decision. For the Best Use of Google AI category, this workflow shows how Gemini in Antigravity
can find a security relevant bug faster and make the fix safer with tests.
I have kept this table to only merged PRs and only bug related ones. No drafts, no closed unmerged, no docs typo fixes. This shows breadth and consistency.
| Project | PR Title | Type | PR Link |
|---|---|---|---|
| topoteretes/cognee | fix(lancedb): automatically prefix windows paths to resolve OS Error 3 for long paths | bug fix | |
All of these are merged and verified in production releases.
I ran pytest tests/ -q
locally and all tests passed. I added a new unit test that specifically covers the None
case. I verified that existing permission tests still pass and I checked cross platform impact as per the contributing guide. No OS specific change was needed for this fix.
The impact is clear. For stability, there are no more crashes when ACP clients send empty responses. For security, the permission system now fails safe to deny. For developer experience, there is now clear behavior for agent builders using custom ACP clients. For reliability, long running hermes sessions no longer die on this edge case.
Permission code should never trust external input. A single missing None
check can break an entire agent session. Writing a reproduction script first makes the fix obvious. Using an agentic IDE like Antigravity helps you see the full picture across many files. Small focused PRs get merged faster than large ones.
If you are starting with open source, start with bugs like this. Small, focused, high impact. That is how you learn and how you win trust from maintainers.
Links
GitHub is https://github.com/aniruddhaadak80
Dev profile is https://dev.to/aniruddhadak
PR discussed is https://github.com/NousResearch/hermes-agent/pull/13457
Challenge page is https://dev.to/bugsmash