[GH-ISSUE #2245] Reminder filters with multiple conditions incorrectly match tasks with multiple reminders using rest API #6616

Closed
opened 2026-04-20 17:12:57 -05:00 by GiteaMirror · 1 comment
Owner

Originally created by @johnsonbeng on GitHub (Feb 16, 2026).
Original GitHub issue: https://github.com/go-vikunja/vikunja/issues/2245

Pre-submission checklist

  • I have searched for existing open or closed issue reports with the same problem.

Description

Problem

When filtering tasks by reminders using multiple range conditions joined with &&, tasks with multiple reminders can be incorrectly included even if no single reminder satisfies all conditions.

Example:

GET /api/v1/tasks?filter=reminders > now && reminders < now+5m

Expected behavior: Return only tasks that have at least one reminder in the (now, now+5m) window.

Actual behavior: Tasks with multiple reminders can be included even if:
One reminder is before now, another reminder is after now+5m for a task wich has no single reminder is actually in the (now, now+5m) window

Note: This bug only occurs when a task has multiple reminders. Tasks with a single reminder work correctly.

How to reproduce:

  1. Create a task with multiple reminders, where none fall within the target window
  2. Set a time window that excludes all reminders, and run the api GET request. For example, use a window from now to now+5m:
    GET /api/v1/tasks?filter=reminders%20%3E%20now%20%26%26%20reminders%20%3C%20now%2B5m&filter_include_nulls=false
  3. Observe the result: the task is returned

Root cause

The bug is in convertFiltersToDBFilterCond in pkg/models/task_search.go. When processing filters on sub-table fields (like reminders), each filter condition is converted into a separate EXISTS subquery:
EXISTS (SELECT 1 FROM task_reminders WHERE tasks.id = task_id AND reminder > now)
AND
EXISTS (SELECT 1 FROM task_reminders WHERE tasks.id = task_id AND reminder < now+5m)

With a single reminder: Both EXISTS checks must pass on the same row, so it behaves correctly.
With multiple reminders:

  • Each EXISTS can be satisfied by different rows:
  • First EXISTS can match a reminder at now+10m (satisfies > now)
  • Second EXISTS can match a reminder at now-10m (satisfies < now+5m)
  • Result: Task is incorrectly included even though no single reminder is in the window.

The problematic code was in the sub-table filter handling section: task_search.go in function convertFiltersToDBFilterCond

Vikunja Version

v1.1.0

Browser and version

No response

Can you reproduce the bug on the Vikunja demo site?

Yes

Screenshots

No response

Originally created by @johnsonbeng on GitHub (Feb 16, 2026). Original GitHub issue: https://github.com/go-vikunja/vikunja/issues/2245 ### Pre-submission checklist - [x] I have searched for existing open or closed issue reports with the same problem. ### Description ### Problem When filtering tasks by reminders using multiple range conditions joined with &&, tasks with multiple reminders can be incorrectly included even if no single reminder satisfies all conditions. ### Example: GET /api/v1/tasks?filter=reminders > now && reminders < now+5m **Expected behavior:** Return only tasks that have at least one reminder in the (now, now+5m) window. **Actual behavior:** Tasks with multiple reminders can be included even if: One reminder is before now, another reminder is after now+5m for a task wich has no single reminder is actually in the (now, now+5m) window Note: This bug only occurs when a task has multiple reminders. Tasks with a single reminder work correctly. **How to reproduce:** 1. Create a task with multiple reminders, where none fall within the target window 2. Set a time window that excludes all reminders, and run the api GET request. For example, use a window from now to now+5m: GET /api/v1/tasks?filter=reminders%20%3E%20now%20%26%26%20reminders%20%3C%20now%2B5m&filter_include_nulls=false 3. Observe the result: the task is returned ### Root cause The bug is in convertFiltersToDBFilterCond in pkg/models/task_search.go. When processing filters on sub-table fields (like reminders), each filter condition is converted into a separate EXISTS subquery: EXISTS (SELECT 1 FROM task_reminders WHERE tasks.id = task_id AND reminder > now) AND EXISTS (SELECT 1 FROM task_reminders WHERE tasks.id = task_id AND reminder < now+5m) With a single reminder: Both EXISTS checks must pass on the same row, so it behaves correctly. With multiple reminders: - Each EXISTS can be satisfied by different rows: - First EXISTS can match a reminder at now+10m (satisfies > now) - Second EXISTS can match a reminder at now-10m (satisfies < now+5m) - Result: Task is incorrectly included even though no single reminder is in the window. The problematic code was in the sub-table filter handling section: task_search.go in function convertFiltersToDBFilterCond ### Vikunja Version v1.1.0 ### Browser and version _No response_ ### Can you reproduce the bug on the Vikunja demo site? Yes ### Screenshots _No response_
Author
Owner

@vikunja-bot-app[bot] commented on GitHub (Feb 19, 2026):

This issue has been fixed in #2260, please check with the next unstable build (should be ready for deployment in ~30min, also on the demo).

<!-- gh-comment-id:3926712289 --> @vikunja-bot-app[bot] commented on GitHub (Feb 19, 2026): This issue has been fixed in #2260, please check with the next unstable build (should be ready for deployment in ~30min, also on [the demo](https://try.vikunja.io)).
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/vikunja#6616