Gateway JSON file UnicodeDecodeError handling

NousResearch/hermes-agent · cluster 28579 · gateway

Data as of

Nothing open on GitHub. Fix merged in #39488. Check it covers your case.

The short answer

0open issues
0open PRs
7items grouped
Known?
Yes. 7 related items grouped here, 1 issue already closed.
Fix event
A fix was merged to main in PR #39488. Check it covers your case. No release data is tracked.
Tracker
The maintainers' tracker marks this unresolved. That is separate from the fix event.
Still open
Nothing open on GitHub.

A bug was reported where corrupted or non-UTF-8 gateway state files cause unhandled UnicodeDecodeError exceptions and persistent warnings. Multiple proposed fixes address catching this error in _read_json_file and related gateway state reads.

Open issues0

No open issues.

Open PRs0

No open pull requests.

Fixes on record

Merged to main. A stamp counts the issues a fix is linked to.

  • #39488 fix(gateway): tolerate non-UTF-8 status/pid files in gateway status reads

    merged to main

    files: gateway/status.py, tests/gateway/test_status.py

    Show the diff
    • gateway/status.py
      @@ -227,7 +227,10 @@ def _read_json_file(path: Path) -> Optional[dict[str, Any]]:
               return None
           try:
               raw = path.read_text(encoding="utf-8").strip()
      -    except OSError:
      +    except (OSError, UnicodeDecodeError):
      +        # OSError: file vanished or permission flipped between exists() and
      +        # read. UnicodeDecodeError: file holds non-UTF-8 / binary garbage
      +        # (a truncated or clobbered status file). Either way it's unusable.
               return None
           if not raw:
               return None
      @@ -249,8 +252,9 @@ def _read_pid_record(pid_path: Optional[Path] = None) -> Optional[dict]:
       
           try:
               raw = pid_path.read_text().strip()
      -    except OSError:
      -        # File was deleted between exists() and read_text(), or permission flipped.
      +    except (OSError, UnicodeDecodeError):
      +        # File was deleted between exists() and read_text(), permission
      +        # flipped, or it holds non-UTF-8 / binary garbage.
               return None
           if not raw:
               return None
    • tests/gateway/test_status.py
      @@ -1036,3 +1036,28 @@ def test_ps_fallback_used_when_proc_returns_empty(self, monkeypatch):
               )
               result = status._read_process_cmdline(12345)
               assert "hermes_cli/main.py" in result
      +
      +
      +class TestCorruptStatusFiles:
      +    """A status / pid file holding non-UTF-8 (binary) bytes must read as
      +    None, not crash the gateway status path with UnicodeDecodeError."""
      +
      +    def test_read_json_file_returns_none_on_binary_garbage(self, tmp_path):
      +        p = tmp_path / "runtime.json"
      +        p.write_bytes(b"\xff\xfe\x00\x80not utf-8\x81")
      +        assert status._read_json_file(p) is None
      +
      +    def test_read_json_file_still_parses_valid_json(self, tmp_path):
      +        p = tmp_path / "runtime.json"
      +        p.write_text(json.dumps({"pid": 7}), encoding="utf-8")
      +        assert status._read_json_file(p) == {"pid": 7}
      +
      +    def test_read_pid_record_returns_none_on_binary_garbage(self, tmp_path):
      +        p = tmp_path / "gateway.pid"
      +        p.write_bytes(b"\xff\xfe\x00\x80\x81")
      +        assert status._read_pid_record(p) is None
      +
      +    def test_read_pid_record_still_parses_bare_pid(self, tmp_path):
      +        p = tmp_path / "gateway.pid"
      +        p.write_text("4242", encoding="utf-8")
      +        assert status._read_pid_record(p) == {"pid": 4242}

5 PRs closed without merging

From the close comments: done elsewhere 3 · merged via another change 1 · superseded by another PR 1

  • #28599 fix: catch UnicodeDecodeError in _read_json_file for corrupted gateway_state.json · done elsewhere → 899ee8c, #28579, #28600
  • #28600 fix(gateway): recover from corrupt runtime state (#28579) · superseded by another PR → #28599
  • #28607 fix(gateway): catch UnicodeDecodeError in _read_json_file for corrupted state files (#28579) · done elsewhere → #39488
  • #29208 fix(gateway): catch UnicodeDecodeError in _read_json_file (#28579) · done elsewhere → 899ee8c
  • #38313 fix(gateway): catch UnicodeDecodeError in _read_json_file · merged via another change → #39488
Closed issues · 1
  • Closed#28579bug: _read_json_file doesn't catch UnicodeDecodeError — corrupted gateway_state.json causes persistent warnings
How this cluster was grouped
  • Link evidence (structural links throughout): every member is connected by structural evidence: shared changed files, or a closing/superseded reference.
  • Pairwise link density 0.29: the share of item pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36. 1.00 means every pair is linked.

Pick up a Lab task

Check whether a fix covers the open issues here, with your own agent. Bring back evidence for maintainers.

Open the Lab

At a glance

Subsystem
gateway
Merged PRs
#39488
Closed issues
1
Attempts
5 PRs closed without merging
Fix link checked
5 Jun 2026

For your agent

The same facts, typed.