Skip to content

fix: guard api_kwargs in except handler to prevent UnboundLocalError - #7376

Merged
teknium1 merged 1 commit into
mainfrom
hermes/hermes-f8dcb6dd
Apr 10, 2026
Merged

fix: guard api_kwargs in except handler to prevent UnboundLocalError#7376
teknium1 merged 1 commit into
mainfrom
hermes/hermes-f8dcb6dd

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Summary

Discord user gruman0 reported getting this error after updating:

Sorry, I encountered an error (UnboundLocalError).
cannot access local variable 'api_kwargs' where it is not associated with a value

Root cause: In the API retry loop in run_conversation(), api_kwargs is assigned inside the try block at line 7712 via _build_api_kwargs(). If that method throws an exception, the except handler tries to pass api_kwargs to _dump_api_request_debug() — but it was never assigned, causing UnboundLocalError that masks the real error.

Two unguarded references:

  1. Line 8743: _dump_api_request_debug(api_kwargs, reason="non_retryable_client_error")
  2. Line 8848: _dump_api_request_debug(api_kwargs, reason="max_retries_exhausted")

Fix:

  • Initialize api_kwargs = None before the retry loop (same pattern as existing response = None guard)
  • Guard both _dump_api_request_debug calls with if api_kwargs is not None:

Note: This fixes the masking bug so the real error surfaces. The user's underlying issue (whatever causes _build_api_kwargs to throw) will now show a descriptive error message instead of the opaque UnboundLocalError.

Test plan

  • Added regression test test_build_api_kwargs_error_no_unbound_local that mocks _build_api_kwargs to raise and verifies the real error propagates
  • All 3 TestRetryExhaustion tests pass
  • Full tests/run_agent/test_run_agent.py suite passes (243 tests)

When _build_api_kwargs() throws an exception, the except handler in
the retry loop referenced api_kwargs before it was assigned. This
caused an UnboundLocalError that masked the real error, making
debugging impossible for the user.

Two _dump_api_request_debug() calls in the except block (non-retryable
client error path and max-retries-exhausted path) both accessed
api_kwargs without checking if it was assigned.

Fix: initialize api_kwargs = None before the retry loop and guard both
dump calls. Now the real error surfaces instead of the masking
UnboundLocalError.

Reported by Discord user gruman0.
@teknium1
teknium1 merged commit ea81aa2 into main Apr 10, 2026
5 of 6 checks passed
Tommyeds pushed a commit to Tommyeds/hermes-agent that referenced this pull request Apr 12, 2026
…ousResearch#7376)

When _build_api_kwargs() throws an exception, the except handler in
the retry loop referenced api_kwargs before it was assigned. This
caused an UnboundLocalError that masked the real error, making
debugging impossible for the user.

Two _dump_api_request_debug() calls in the except block (non-retryable
client error path and max-retries-exhausted path) both accessed
api_kwargs without checking if it was assigned.

Fix: initialize api_kwargs = None before the retry loop and guard both
dump calls. Now the real error surfaces instead of the masking
UnboundLocalError.

Reported by Discord user gruman0.
02356abc pushed a commit to 02356abc/hermes-agent that referenced this pull request May 14, 2026
…ousResearch#7376)

When _build_api_kwargs() throws an exception, the except handler in
the retry loop referenced api_kwargs before it was assigned. This
caused an UnboundLocalError that masked the real error, making
debugging impossible for the user.

Two _dump_api_request_debug() calls in the except block (non-retryable
client error path and max-retries-exhausted path) both accessed
api_kwargs without checking if it was assigned.

Fix: initialize api_kwargs = None before the retry loop and guard both
dump calls. Now the real error surfaces instead of the masking
UnboundLocalError.

Reported by Discord user gruman0.
gweeteve pushed a commit to gweeteve/hermes-agent that referenced this pull request Jun 2, 2026
…ousResearch#7376)

When _build_api_kwargs() throws an exception, the except handler in
the retry loop referenced api_kwargs before it was assigned. This
caused an UnboundLocalError that masked the real error, making
debugging impossible for the user.

Two _dump_api_request_debug() calls in the except block (non-retryable
client error path and max-retries-exhausted path) both accessed
api_kwargs without checking if it was assigned.

Fix: initialize api_kwargs = None before the retry loop and guard both
dump calls. Now the real error surfaces instead of the masking
UnboundLocalError.

Reported by Discord user gruman0.
waefrebeorn pushed a commit to waefrebeorn/slermes that referenced this pull request Jul 2, 2026
…ousResearch#7376)

When _build_api_kwargs() throws an exception, the except handler in
the retry loop referenced api_kwargs before it was assigned. This
caused an UnboundLocalError that masked the real error, making
debugging impossible for the user.

Two _dump_api_request_debug() calls in the except block (non-retryable
client error path and max-retries-exhausted path) both accessed
api_kwargs without checking if it was assigned.

Fix: initialize api_kwargs = None before the retry loop and guard both
dump calls. Now the real error surfaces instead of the masking
UnboundLocalError.

Reported by Discord user gruman0.
skappafrost pushed a commit to skappafrost/hermes-agent that referenced this pull request Aug 15, 2026
…ousResearch#7376)

When _build_api_kwargs() throws an exception, the except handler in
the retry loop referenced api_kwargs before it was assigned. This
caused an UnboundLocalError that masked the real error, making
debugging impossible for the user.

Two _dump_api_request_debug() calls in the except block (non-retryable
client error path and max-retries-exhausted path) both accessed
api_kwargs without checking if it was assigned.

Fix: initialize api_kwargs = None before the retry loop and guard both
dump calls. Now the real error surfaces instead of the masking
UnboundLocalError.

Reported by Discord user gruman0.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant