Skip to content

fix(watch-data): use sentinel values to avoid invalid SQL syntax#2552

Merged
gauthier-th merged 2 commits intodevelopfrom
0xsysr3ll/fix/tautulli-watch-data-empty
Feb 23, 2026
Merged

fix(watch-data): use sentinel values to avoid invalid SQL syntax#2552
gauthier-th merged 2 commits intodevelopfrom
0xsysr3ll/fix/tautulli-watch-data-empty

Conversation

@0xSysR3ll
Copy link
Copy Markdown
Contributor

@0xSysR3ll 0xSysR3ll commented Feb 22, 2026

Description

When Tautulli returns no watchers, the query used IN (), which is invalid.
This PR fixes this by pushing sentinel values so the list is never empty and no real rows match.

  • Fixes #XXXX

How Has This Been Tested?

Screenshots / Logs (if applicable)

Checklist:

  • I have read and followed the contribution guidelines.
  • Disclosed any use of AI (see our policy)
  • I have updated the documentation accordingly.
  • All new and existing tests passed.
  • Successful build pnpm build
  • Translation keys pnpm i18n:extract
  • Database migration (if required)

Summary by CodeRabbit

  • Refactor
    • Improved database query reliability for user information lookups to ensure consistent handling across all data retrieval scenarios.

@0xSysR3ll 0xSysR3ll added the bug Something isn't working label Feb 22, 2026
@0xSysR3ll 0xSysR3ll requested a review from a team as a code owner February 22, 2026 16:08
@0xSysR3ll 0xSysR3ll changed the title 0xsysr3ll/fix/tautulli watch data empty fix(watch_data): use sentinel values to avoid invalid SQL syntax Feb 22, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 22, 2026

📝 Walkthrough

Walkthrough

Refactored database query patterns in Plex user lookups across two route handlers. Precomputed plexIds and plexEmails arrays replace inline query mapping. Added sentinel values to prevent empty IN clauses in SQL queries.

Changes

Cohort / File(s) Summary
Tautulli Watch User Lookups
server/routes/media.ts
Precomputed plexIds array from watchUsers.user_id with sentinel value (-1) appended when empty; replaced inline mapping in both standard and 4K watch data query paths.
Plex User Workflow
server/routes/settings/index.ts
Precomputed plexIds (from plexUser.id) and plexEmails (normalized to lowercase) arrays with sentinel values ('-1' for ids, '@' for emails) when empty; refactored both user lookup and existingUsers queries to use precomputed arrays via IN conditions instead of inline mapping.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 Array-bound queries, precomputed with care,
Sentinel sentries guard the IN clause's fair,
No more inline maps, just arrays so clean,
Empty or full, robust routines!
A rabbit hops on, the code runs with glee! ✨

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: using sentinel values to prevent invalid SQL syntax in watch-data queries.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR prevents invalid SQL (IN ()) when building TypeORM IN (:...ids) queries with potentially-empty arrays (e.g., when Tautulli returns no watchers), by ensuring query parameter arrays are never empty.

Changes:

  • Add sentinel values to Plex/Tautulli ID/email arrays so IN (:...param) never receives an empty list.
  • Refactor query parameter construction to reuse precomputed plexIds / plexEmails arrays.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
server/routes/settings/index.ts Ensures the /settings/plex/users existing-user lookup doesn’t generate IN () when Plex returns no eligible users.
server/routes/media.ts Ensures the /:id/watch_data user lookup doesn’t generate IN () when Tautulli returns no watchers (both SDR and 4K paths).
Comments suppressed due to low confidence (2)

server/routes/settings/index.ts:501

  • user.plexId is stored as an integer (number | null), but here plexIds is built from Plex's string IDs and the sentinel is pushed as a string. Consider normalizing plexIds to number[] up-front (e.g., parseInt once) and using a numeric sentinel (e.g., -1) to keep parameter types aligned with the DB column and avoid relying on implicit casting.
      const plexIds = plexUsers.map((plexUser) => plexUser.id);
      const plexEmails = plexUsers.map((plexUser) =>
        plexUser.email.toLowerCase()
      );
      if (!plexIds.length) plexIds.push('-1');

server/routes/settings/index.ts:506

  • PR title/description focuses on watch_data, but this hunk also changes the /settings/plex/users query behavior. Please either update the PR description/title to mention this additional fix, or split it into a separate PR so the scope matches what reviewers expect.
      const existingUsers = await qb
        .where('user.plexId IN (:...plexIds)', { plexIds })
        .orWhere('user.email IN (:...plexEmails)', { plexEmails })

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Collaborator

@fallenbagel fallenbagel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Success!

@gauthier-th gauthier-th changed the title fix(watch_data): use sentinel values to avoid invalid SQL syntax fix(watch-data): use sentinel values to avoid invalid SQL syntax Feb 23, 2026
@gauthier-th gauthier-th merged commit 947f70c into develop Feb 23, 2026
21 of 22 checks passed
@gauthier-th gauthier-th deleted the 0xsysr3ll/fix/tautulli-watch-data-empty branch February 23, 2026 20:24
alexlebens pushed a commit to alexlebens/infrastructure that referenced this pull request Feb 27, 2026
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [ghcr.io/seerr-team/seerr](https://github.com/seerr-team/seerr) | minor | `v3.0.1` → `v3.1.0` |
| [seerr-team/seerr](https://github.com/seerr-team/seerr) | minor | `v3.0.1` → `v3.1.0` |

---

### Release Notes

<details>
<summary>seerr-team/seerr (ghcr.io/seerr-team/seerr)</summary>

### [`v3.1.0`](https://github.com/seerr-team/seerr/releases/tag/v3.1.0)

[Compare Source](seerr-team/seerr@v3.0.1...v3.1.0)

##### 🛡️ Security

- Patch [CVE-2026-27707](GHSA-rc4w-7m3r-c2f7)  - Unauthenticated account registration on Plex-configured Seerr instances via Jellyfin authentication endpoint  - ([4ae2068](seerr-team/seerr@4ae2068))
- Patch [CVE-2026-27793](GHSA-f7xw-jcqr-57hp) - Broken Object-Level Authorization in User Profile Endpoint Exposes Third-Party Notification Credentials - ([4f089b2](seerr-team/seerr@4f089b2))
- Patch [CVE-2026-27792](GHSA-gx3h-3jg5-q65f)  - Missing authentication on pushSubscription endpoints  - ([946bdecec](seerr-team/seerr@946bdec))

##### 🚀 Features

- *(helm)* Use an existing PVC as config volume ([#&#8203;2447](seerr-team/seerr#2447)) - ([8f0c904](seerr-team/seerr@8f0c904))
- *(servarr-api)* Make Servarr API request timeout configurable ([#&#8203;2556](seerr-team/seerr#2556)) - ([3bcb4da](seerr-team/seerr@3bcb4da))
- Self-host font for better privacy ([#&#8203;2540](seerr-team/seerr#2540)) - ([10ea21b](seerr-team/seerr@10ea21b))

##### 🐛 Bug Fixes

- *(helm)* Add "v" as prefix for appVersion tag ([#&#8203;2445](seerr-team/seerr#2445)) - ([04b9d87](seerr-team/seerr@04b9d87))
- *(jellyfin-scanner)* Include unmatched seasons in processable seasons ([#&#8203;2538](seerr-team/seerr#2538)) - ([68f56d2](seerr-team/seerr@68f56d2))
- *(link-account)* Fix error-message override ([#&#8203;2547](seerr-team/seerr#2547)) - ([b843be0](seerr-team/seerr@b843be0))
- *(plex-scanner)* Add TVDb to TMDB fallback in plex scanner ([#&#8203;2537](seerr-team/seerr#2537)) - ([7c60a5c](seerr-team/seerr@7c60a5c))
- *(radarr)* Trigger search for existing monitored movies without files ([#&#8203;2391](seerr-team/seerr#2391)) - ([55776ea](seerr-team/seerr@55776ea))
- *(servarr)* Increase default API timeout from 5000ms to 10000ms ([#&#8203;2442](seerr-team/seerr#2442)) - ([b499976](seerr-team/seerr@b499976))
- *(sonarr)* Use configured metadata provider for season filtering ([#&#8203;2516](seerr-team/seerr#2516)) - ([5013d1d](seerr-team/seerr@5013d1d))
- *(watch-data)* Use sentinel values to avoid invalid SQL syntax ([#&#8203;2552](seerr-team/seerr#2552)) - ([947f70c](seerr-team/seerr@947f70c))
- *(watchlist-sync)* Correct permission typo for TV auto requests ([#&#8203;2488](seerr-team/seerr#2488)) - ([e0e4b6f](seerr-team/seerr@e0e4b6f))
- Preserve blocklist on media deletion & optimise watchlist-sync ([#&#8203;2478](seerr-team/seerr#2478)) - ([9da8bb6](seerr-team/seerr@9da8bb6))

##### 🚜 Refactor

- *(tailwind)* Replace deprecated tailwind utilities ([#&#8203;2542](seerr-team/seerr#2542)) - ([f42a4ec](seerr-team/seerr@f42a4ec))

##### 📖 Documentation

- *(synology)* Add installation guide via SynoCommunity ([#&#8203;2503](seerr-team/seerr#2503)) - ([0e636a3](seerr-team/seerr@0e636a3))
- *(truenas)* Update install/migration guide ([#&#8203;2491](seerr-team/seerr#2491)) - ([dc1734d](seerr-team/seerr@dc1734d))
- *(unraid)* Improve unraid migration guide  ([#&#8203;2470](seerr-team/seerr#2470)) - ([5e64d49](seerr-team/seerr@5e64d49))
- Update Unraid install and migration guides with dual permission methods ([#&#8203;2532](seerr-team/seerr#2532)) - ([a0d0eb1](seerr-team/seerr@a0d0eb1))
- Add a warning in migration-guide for third party installation ([#&#8203;2527](seerr-team/seerr#2527)) - ([7e9dff3](seerr-team/seerr@7e9dff3))
- Remove double quotes (") from DB\_HOST environment variable ([#&#8203;2514](seerr-team/seerr#2514)) - ([fa905be](seerr-team/seerr@fa905be))
- Add Unraid installation and migration guide ([#&#8203;2440](seerr-team/seerr#2440)) - ([b6a9132](seerr-team/seerr@b6a9132))
- Fix migration guide title ([#&#8203;2425](seerr-team/seerr#2425)) - ([39ae32f](seerr-team/seerr@39ae32f))

##### ⚡ Performance

- Add missing indexes on all foreign key columns ([#&#8203;2461](seerr-team/seerr#2461)) - ([c6bcfe0](seerr-team/seerr@c6bcfe0))

##### ⚙️ Miscellaneous Tasks

- *(changelog)* Fix changelog template ([#&#8203;2431](seerr-team/seerr#2431)) - ([c2977f6](seerr-team/seerr@c2977f6))
- *(eslint)* Add react/self-closing-comp ([#&#8203;2563](seerr-team/seerr#2563)) - ([cd8b386](seerr-team/seerr@cd8b386))
- *(github)* Add docs and maintenance issue templates ([#&#8203;2467](seerr-team/seerr#2467)) - ([cf4883a](seerr-team/seerr@cf4883a))
- *(helm)* Add GatewayAPI route support to helm chart ([#&#8203;2544](seerr-team/seerr#2544)) - ([3a42f59](seerr-team/seerr@3a42f59))
- *(helm)* Update ghcr.io/seerr-team/seerr ( 3.0.0 → 3.0.1 ) \[skip-ci] ([#&#8203;2441](seerr-team/seerr#2441)) - ([87fb0df](seerr-team/seerr@87fb0df))
- *(husky)* Fixed husky commit message from bash/zsh syntax to sh syntax ([#&#8203;2572](seerr-team/seerr#2572)) - ([a00c9e5](seerr-team/seerr@a00c9e5))
- *(release)* Prepare ${TAG\_VERSION} - ([94a70bb](seerr-team/seerr@94a70bb))
- Updated the Contributing and Security guides to reflect our current practices ([#&#8203;2579](seerr-team/seerr#2579)) - ([0d40a42](seerr-team/seerr@0d40a42))
- Disable nextjs telemetry ([#&#8203;2517](seerr-team/seerr#2517)) - ([cecdd63](seerr-team/seerr@cecdd63))
- Update contributing guide regarding Automated AI Agent ([#&#8203;2518](seerr-team/seerr#2518)) - ([880fbc9](seerr-team/seerr@880fbc9))
- Remove discord notification from release ([#&#8203;2501](seerr-team/seerr#2501)) - ([fba20c1](seerr-team/seerr@fba20c1))
- Add create-tag workflow to streamline release process ([#&#8203;2493](seerr-team/seerr#2493)) - ([06e5eb0](seerr-team/seerr@06e5eb0))
- Update concurrency logic ([#&#8203;2481](seerr-team/seerr#2481)) - ([4939f13](seerr-team/seerr@4939f13))
- Add semantic-pr workflow to enforce conventional commits ([#&#8203;2472](seerr-team/seerr#2472)) - ([5e57fdc](seerr-team/seerr@5e57fdc))

##### New Contributors ❤️

- [@&#8203;caillou](https://github.com/caillou) made their first contribution
- [@&#8203;Kenshin9977](https://github.com/Kenshin9977) made their first contribution
- [@&#8203;MagicLegend](https://github.com/MagicLegend) made their first contribution
- [@&#8203;wiiaam](https://github.com/wiiaam) made their first contribution
- [@&#8203;mjonkus](https://github.com/mjonkus) made their first contribution
- [@&#8203;nova-api](https://github.com/nova-api) made their first contribution
- [@&#8203;mreid-tt](https://github.com/mreid-tt) made their first contribution
- [@&#8203;DataBitz](https://github.com/DataBitz) made their first contribution
- [@&#8203;Hyperion2220](https://github.com/Hyperion2220) made their first contribution
- [@&#8203;blassley](https://github.com/blassley) made their first contribution
- [@&#8203;JanKleine](https://github.com/JanKleine) made their first contribution
- [@&#8203;koiralasandesh](https://github.com/koiralasandesh) made their first contribution<!-- generated by git-cliff -->

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about these updates again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yNS43IiwidXBkYXRlZEluVmVyIjoiNDMuMjUuNyIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiaW1hZ2UiXX0=-->

Reviewed-on: https://gitea.alexlebens.dev/alexlebens/infrastructure/pulls/4284
Co-authored-by: Renovate Bot <renovate-bot@alexlebens.net>
Co-committed-by: Renovate Bot <renovate-bot@alexlebens.net>
lucianchauvin pushed a commit to lucianchauvin/jellyseerr that referenced this pull request Apr 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants