# [RNS 1.2.5] InterfaceAnnouncer.sanitize() crashes with AttributeError when reachable_on or discovery_name is None

_General · started by PAzter1101 on Wed, May 13, 2026 7:47 AM_

Tags: Discussion, Help

---

## Original post

**PAzter1101** · Wed, May 13, 2026 7:47 AM

Running RNS 1.2.5 with a config that doesn't set `reachable_on` on my local `TCPServerInterface` — the discovery thread crashes every JOB_INTERVAL with:

```
[Error] Error while preparing interface discovery announces: 'NoneType' object has no attribute 'replace'
[Error] An unhandled <class 'AttributeError'> exception occurred: 'NoneType' object has no attribute 'replace'
Traceback (most recent call last):
  File ".../RNS/Discovery.py", line 78, in job
    app_data = self.get_interface_announce_data(selected_interface)
  File ".../RNS/Discovery.py", line 114, in get_interface_announce_data
    reachable_on = self.sanitize(interface.reachable_on)
  File ".../RNS/Discovery.py", line 89, in sanitize
    sanitized = in_str.replace("\n", "")
                ^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'replace'
```

The discovery announce never goes out.

## Root cause

`InterfaceAnnouncer.sanitize` calls `in_str.replace("\n", "")` without a None-check. It is invoked against `interface.discovery_name` (line 104) and `interface.reachable_on` (line 114), both of which can legitimately be `None` on an interface whose operator didn't set them in the config. The sibling helper `InterfaceAnnouncer.sanitize_name` (line 204) already early-outs on falsy input: `if not name: return None`.

## Patch

```diff
     def sanitize(self, in_str):
+        if in_str is None: return None
         sanitized = in_str.replace("\n", "")
         sanitized = sanitized.replace("\r", "")
         sanitized = sanitized.strip()
         return sanitized
```

Downstream callers already cope with a `None` return — the non-windows `reachable_on` branch wraps the subsequent `os.path.expanduser` in `try/except` and aborts the announce cleanly, and missing fields are simply omitted from the announce payload. Net behaviour: that one announce is skipped, the discovery thread keeps running.

## Branch with the fix + regression test

Since the upstream repo doesn't accept external PRs/Issues/Discussions, I put the change on a fork — one-line fix plus a small `tests/discovery.py` regression test that bypasses the heavy `InterfaceAnnouncer.__init__` via `__new__`:

https://github.com/markqvist/Reticulum/compare/master...PAzter1101:fix/discovery-sanitize-none-input

Happy to send the patch in whatever form is easiest if a fork-branch link is inconvenient.

---

## Reply 1

**Mark** · Wed, May 13, 2026 8:37 AM

Thanks PAzter1101. Verified and patched in:

[c86b9c97032f1ffeeeb8d02b43faae8c321aff93](a8d24177d946de4f1f0a0fe1af9a1338:/page/commit.mu`g=reticulum|r=reticulum|h=c86b9c97032f1ffeeeb8d02b43faae8c321aff93)

Will be released shortly.

---

## Reply 2

**PAzter1101** · Thu, May 14, 2026 7:51 AM

**Mark** wrote:
> Thanks PAzter1101. Verified and patched in:
> 
> [c86b9c97032f1ffeeeb8d02b43faae8c321aff93](a8d24177d946de4f1f0a0fe1af9a1338:/page/commit.mu`g=reticulum|r=reticulum|h=c86b9c97032f1ffeeeb8d02b43faae8c321aff93)
> 
> Will be released shortly.

Thanks Mark — great turnaround. Will pick it up once the next release lands on the public mirror.

---

## Reply 3

**PAzter1101** · Thu, May 14, 2026 7:57 AM

...

---

## Reply 4

**Mark** · Thu, May 14, 2026 8:10 AM

It's out on pip now

---

## Reply 5

**daylight-hub** · Fri, May 15, 2026 12:26 AM

**Mark** wrote:
> Thanks PAzter1101. Verified and patched in:
> 
> [c86b9c97032f1ffeeeb8d02b43faae8c321aff93](a8d24177d946de4f1f0a0fe1af9a1338:/page/commit.mu`g=reticulum|r=reticulum|h=c86b9c97032f1ffeeeb8d02b43faae8c321aff93)
> 
> Will be released shortly.

Can you give clear instructions how to use rngit? What testnet do I have to be connected to, any special configurations in the config file, what exact command to download and install the latest version? I'm currently on RNS 1.2.5.

---
