fix(tasks): remove non-functional reminder write params (v1.1.2)

Exhaustive FW_DEBUG investigation on both Free and Premium accounts
confirmed that taskupdate2 silently ignores all reminder fields regardless
of encoding (flat, JSON-string, PHP-bracket, all variants). Alternative
endpoints (tasksetalert etc.) are unregistered. Root cause: mobile app
Service Worker transforms reminder requests in ways not reproducible via
direct API calls. Reminders remain read-only. Recurrency write confirmed
working (flat encoding). Docs updated with full investigation findings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-17 21:35:23 +02:00
parent 08ee5fb84a
commit d6d8d40305
5 changed files with 46 additions and 47 deletions
+8 -36
View File
@@ -930,15 +930,17 @@ def update_task(
recurrency_interval: int | None = None,
rrule: str | None = None,
clear_recurrency: bool = False,
reminder_unit: str | None = None,
reminder_value: int | None = None,
clear_reminder: bool = False,
) -> str:
"""Update an existing task's fields.
IMPORTANT: Ask the user for confirmation before calling this tool.
At least one parameter besides *task_id* must be provided.
NOTE: Setting or clearing reminders is **not supported** via this tool.
The Family Wall API does not accept reminder writes through ``taskupdate2``
— reminder updates are handled exclusively by the mobile app's Service
Worker and cannot be replicated via direct API calls.
Args:
task_id: Task metaId from get_tasks.
text: New title text (omit to leave unchanged).
@@ -967,14 +969,6 @@ def update_task(
Overrides simple recurrency fields when set.
clear_recurrency: Set to ``True`` to remove the recurrence rule from the task.
Cannot be used together with *recurrency*.
reminder_unit: Unit for the reminder offset — ``"MINUTE"``, ``"HOUR"``, or
``"DAY"``. Must be provided together with *reminder_value*. Requires a
*due_date* to be set on the task.
reminder_value: Offset before the due date/time (e.g. ``0`` = at the time,
``15`` = 15 min before, ``1`` with unit ``"DAY"`` = 1 day before).
Must be provided together with *reminder_unit*.
clear_reminder: Set to ``True`` to remove the reminder from the task.
Cannot be used together with *reminder_unit*/*reminder_value*.
Returns:
JSON success indicator or an error message.
@@ -983,12 +977,6 @@ def update_task(
return _err("'clear_due_date' and 'due_date' cannot be used together.")
if clear_recurrency and recurrency is not None:
return _err("'clear_recurrency' and 'recurrency' cannot be used together.")
if clear_reminder and (reminder_unit is not None or reminder_value is not None):
return _err(
"'clear_reminder' cannot be used together with 'reminder_unit'/'reminder_value'."
)
if (reminder_unit is None) != (reminder_value is None):
return _err("'reminder_unit' and 'reminder_value' must be provided together.")
if (
text is None
@@ -1000,14 +988,11 @@ def update_task(
and list_id is None
and recurrency is None
and not clear_recurrency
and reminder_unit is None
and not clear_reminder
):
return _err(
"At least one of 'text', 'description', 'category_id', 'due_date',"
" 'clear_due_date', 'assignee_ids', 'list_id', 'recurrency',"
" 'clear_recurrency', 'reminder_unit'/'reminder_value', or"
" 'clear_reminder' must be provided."
" 'clear_due_date', 'assignee_ids', 'list_id', 'recurrency', or"
" 'clear_recurrency' must be provided."
)
params: dict[str, Any] = {"metaId": task_id}
@@ -1027,9 +1012,7 @@ def update_task(
if list_id is not None:
params["taskListId"] = list_id
# The FiZ Ai() encoder serialises all fields flat at the top level of the
# request body — nested objects are NOT supported. recurrencyDescriptor and
# reminder fields must therefore be sent as plain top-level parameters.
# Recurrency fields are sent flat at the top level (verified: FiZ Ai() encoder).
if clear_recurrency:
params["recurrency"] = "NONE"
elif recurrency is not None:
@@ -1039,17 +1022,6 @@ def update_task(
if rrule is not None:
params["rrule"] = rrule
if clear_reminder:
params["reminderUnit"] = ""
params["reminderValue"] = 0
params["reminderType"] = "SNOOZE"
params["localId"] = 0
elif reminder_unit is not None and reminder_value is not None:
params["reminderUnit"] = reminder_unit
params["reminderValue"] = reminder_value
params["reminderType"] = "SNOOZE"
params["localId"] = 0
try:
_authenticated_call("taskupdate2", params)
except RuntimeError as exc: