fix(reminders): sanitize ntfy Title header to ASCII (#5208)

* fix(reminders): sanitize ntfy Title header to ASCII

The ntfy notification Title header was set directly from the note title.
HTTP headers must be ASCII, so a title containing emoji or other
non-ASCII characters caused httpx to raise UnicodeEncodeError, which
was swallowed by the surrounding try/except — so the reminder silently
failed and no notification was ever sent.

Sanitize the title with encode('ascii', 'replace') before placing it
into the header, replacing unsupported characters with '?'. This is
standard practice for HTTP header values. The note body is unaffected
(it is sent as request content, not a header) and continues to support
full UTF-8.

* fix(reminders): also truncate ntfy title to 200 chars for header safety

* style: compact ntfy header comment

---------

Co-authored-by: Am-GJ <Am-GJ@users.noreply.github.com>
Co-authored-by: RaresKeY <158580472+RaresKeY@users.noreply.github.com>
This commit is contained in:
Am-GJ
2026-07-11 00:50:00 +04:00
committed by GitHub
parent 807e92c3bc
commit 4901a96591
+3 -1
View File
@@ -479,7 +479,9 @@ async def dispatch_reminder(
base = intg["base_url"].rstrip("/")
topic = settings.get("reminder_ntfy_topic") or "reminders"
ntfy_body = synthesis or note_body or title
hdrs = {"Title": title or "Reminder", "Priority": "high", "Tags": "bell"}
# ntfy Title is an ASCII HTTP header; sanitize Unicode and cap its length.
_clean_title = (title or "Reminder").encode("ascii", "replace").decode("ascii")[:200]
hdrs = {"Title": _clean_title, "Priority": "high", "Tags": "bell"}
api_key = intg.get("api_key", "")
if api_key:
hdrs["Authorization"] = f"Bearer {api_key}"