hermes - 💡(How to fix) Fix SyntaxWarning: return in finally block in _voice_process_recording (Python 3.14+) [2 pull requests]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

On Python 3.14+, cli.py raises a SyntaxWarning at startup due to a return statement inside a finally block in the _voice_process_recording method (line 8700). This is a known pitfall since Python 3.8 — return in a finally block suppresses any exception that was propagating through the finally clause, and Python 3.14 now emits a SyntaxWarning for it.

Error Message

finally: with self._voice_lock: self._voice_processing = False if hasattr(self, "_app") and self._app: self._app.invalidate() try: if wav_path and os.path.isfile(wav_path): os.unlink(wav_path) except Exception: pass

if not submitted:
    self._no_speech_count = getattr(self, "_no_speech_count", 0) + 1
    if self._no_speech_count >= 3:
        self._voice_continuous = False
        self._no_speech_count = 0
        _cprint(f"{_DIM}No speech detected 3 times, continuous mode stopped.{_RST}")
        return  # <--- SyntaxWarning here
else:
    self._no_speech_count = 0

if self._voice_continuous and not submitted and not self._voice_recording:
    ...

Root Cause

On Python 3.14+, cli.py raises a SyntaxWarning at startup due to a return statement inside a finally block in the _voice_process_recording method (line 8700). This is a known pitfall since Python 3.8 — return in a finally block suppresses any exception that was propagating through the finally clause, and Python 3.14 now emits a SyntaxWarning for it.

Fix Action

Fixed

Code Example

finally:
    with self._voice_lock:
        self._voice_processing = False
    if hasattr(self, "_app") and self._app:
        self._app.invalidate()
    try:
        if wav_path and os.path.isfile(wav_path):
            os.unlink(wav_path)
    except Exception:
        pass

    if not submitted:
        self._no_speech_count = getattr(self, "_no_speech_count", 0) + 1
        if self._no_speech_count >= 3:
            self._voice_continuous = False
            self._no_speech_count = 0
            _cprint(f"{_DIM}No speech detected 3 times, continuous mode stopped.{_RST}")
            return  # <--- SyntaxWarning here
    else:
        self._no_speech_count = 0

    if self._voice_continuous and not submitted and not self._voice_recording:
        ...

---

finally:
    with self._voice_lock:
        self._voice_processing = False
    if hasattr(self, "_app") and self._app:
        self._app.invalidate()
    try:
        if wav_path and os.path.isfile(wav_path):
            os.unlink(wav_path)
    except Exception:
        pass

# Business logic outside finally:
if not submitted:
    ...
else:
    ...
if self._voice_continuous and not submitted and not self._voice_recording:
    ...
RAW_BUFFERClick to expand / collapse

Description

On Python 3.14+, cli.py raises a SyntaxWarning at startup due to a return statement inside a finally block in the _voice_process_recording method (line 8700). This is a known pitfall since Python 3.8 — return in a finally block suppresses any exception that was propagating through the finally clause, and Python 3.14 now emits a SyntaxWarning for it.

Location

cli.py, method _voice_process_recording, around line 8681–8716

The Problem

The finally block (line 8681) contains business logic that includes a return statement (line 8700), which triggers the warning:

finally:
    with self._voice_lock:
        self._voice_processing = False
    if hasattr(self, "_app") and self._app:
        self._app.invalidate()
    try:
        if wav_path and os.path.isfile(wav_path):
            os.unlink(wav_path)
    except Exception:
        pass

    if not submitted:
        self._no_speech_count = getattr(self, "_no_speech_count", 0) + 1
        if self._no_speech_count >= 3:
            self._voice_continuous = False
            self._no_speech_count = 0
            _cprint(f"{_DIM}No speech detected 3 times, continuous mode stopped.{_RST}")
            return  # <--- SyntaxWarning here
    else:
        self._no_speech_count = 0

    if self._voice_continuous and not submitted and not self._voice_recording:
        ...

The Fix

Move the business logic out of the finally block:

finally:
    with self._voice_lock:
        self._voice_processing = False
    if hasattr(self, "_app") and self._app:
        self._app.invalidate()
    try:
        if wav_path and os.path.isfile(wav_path):
            os.unlink(wav_path)
    except Exception:
        pass

# Business logic outside finally:
if not submitted:
    ...
else:
    ...
if self._voice_continuous and not submitted and not self._voice_recording:
    ...

Environment

  • Python 3.14.4
  • Hermes Agent v0.12.0
  • Ubuntu 26.04 (WSL2)
  • Warning: SyntaxWarning: return in a finally block

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING