Skip to content

[Bug] Smart Scopes imploding when using date-based scopes #508

Description

@Dukko

What went wrong?

When I make a smart scope showing the recently read books in the last 30 days, it breaks. Additionally, now all my smart scopes are gone:

Image

Steps to reproduce

  1. Create a new smart scope
  2. Set Date Read and "within last 30 days" as the scope.
  3. Save it.

Expected vs actual behavior

Expected to show me my last read books, ended up crashing the entire smart scope section.

Your setup

  • Bookorbit v2.0.1
  • Docker deployed
  • ZimaOS

Relevant logs (optional)

bookorbit_postgres  | 2026-07-02 16:03:47.347 UTC [293290] ERROR:  operator does not exist: date >= integer at character 1082
bookorbit_postgres  | 2026-07-02 16:03:47.347 UTC [293290] HINT:  No operator matches the given name and argument types. You might need to add explicit type casts.
bookorbit_postgres  | 2026-07-02 16:03:47.347 UTC [293290] STATEMENT:  select "books"."id", "books"."status", "books"."primary_file_id", "books"."folder_path", "books"."added_at", "books"."updated_at", "book_metadata"."title", "book_metadata"."series_id", "book_metadata"."series_name", "book_metadata"."series_index", "book_metadata"."published_year", "book_metadata"."language", "user_book_ratings"."rating", "book_metadata"."cover_source", "book_metadata"."locked_fields", "book_metadata"."subtitle", "book_metadata"."publisher", "book_metadata"."page_count", "book_metadata"."isbn13", "book_metadata"."hardcover_id", "book_metadata"."hardcover_edition_id", "book_metadata"."metadata_score", count(*) over() as "_total" from "books" left join "book_metadata" on "book_metadata"."book_id" = "books"."id" left join "user_book_ratings" on ("user_book_ratings"."book_id" = "books"."id" and "user_book_ratings"."user_id" = $1) where (("books"."library_id" in ($2, $3, $4) and (SELECT ("user_book_status"."finished_at" AT TIME ZONE $5)::date FROM "user_book_status" WHERE "user_book_status"."book_id" = "books"."id" AND "user_book_status"."user_id" = $6) >= (timezone($7, now())::date - $8)) and "books"."status" <> $9) order by "book_metadata"."title" ASC NULLS LAST, "books"."id" ASC limit $10

bookorbit_postgres  | 2026-07-02 16:03:54.067 UTC [293371] ERROR:  operator does not exist: date >= integer at character 327
bookorbit_postgres  | 2026-07-02 16:03:54.067 UTC [293371] HINT:  No operator matches the given name and argument types. You might need to add explicit type casts.
bookorbit_postgres  | 2026-07-02 16:03:54.067 UTC [293371] STATEMENT:  select count(*) from "books" left join "book_metadata" on "book_metadata"."book_id" = "books"."id" where (("books"."library_id" in ($1, $2, $3) and (SELECT ("user_book_status"."finished_at" AT TIME ZONE $4)::date FROM "user_book_status" WHERE "user_book_status"."book_id" = "books"."id" AND "user_book_status"."user_id" = $5) >= (timezone($6, now())::date - $7)) and "books"."status" <> $8)

bookorbit           | {"level":50,"time":1783008227349,"pid":7,"hostname":"a72f13f989fa","req":{"id":"req-l58","method":"POST","url":"/api/v1/books/query"},"context":"GlobalExceptionFilter","err":{"type":"DrizzleQueryError","message":"Failed query: select \"books\".\"id\" ... from \"books\" left join \"book_metadata\" on \"book_metadata\".\"book_id\" = \"books\".\"id\" left join \"user_book_ratings\" on (\"user_book_ratings\".\"book_id\" = \"books\".\"id\" and \"user_book_ratings\".\"user_id\" = $1) where ((\"books\".\"library_id\" in ($2, $3, $4) and (SELECT (\"user_book_status\".\"finished_at\" AT TIME ZONE $5)::date FROM \"user_book_status\" WHERE \"user_book_status\".\"book_id\" = \"books\".\"id\" AND \"user_book_status\".\"user_id\" = $6) >= (timezone($7, now())::date - $8)) and \"books\".\"status\" <> $9) order by \"book_metadata\".\"title\" ASC NULLS LAST, \"books\".\"id\" ASC limit $10\nparams: 1,3,1,2,America/Chicago,1,America/Chicago,29,processing,1: operator does not exist: date >= integer","stack":"Error: Failed query: ...\n    at NodePgPreparedQuery.queryWithCache (/app/node_modules/.pnpm/[email protected]_@[email protected][email protected]_@[email protected][email protected]/node_modules/drizzle-orm/pg-core/session.cjs:66:15)\n    at process.processTicksAndRejections (node:internal/process/task_queues:103:5)\n    at async /app/node_modules/.pnpm/[email protected]_@[email protected][email protected]_@[email protected][email protected]/node_modules/drizzle-orm/node-postgres/session.cjs:152:22\n    at async BookRepository.findCards (/app/dist/modules/book/book.repository.js:72:22)\n    at async BookService.executeBooksQuery (/app/dist/modules/book/book.service.js:852:137)\ncaused by: error: operator does not exist: date >= integer\n    at /app/node_modules/.pnpm/[email protected][email protected]/node_modules/pg-pool/index.js:45:11\n    at process.processTicksAndRejections (node:internal/process/task_queues:103:5)\n    at async /app/node_modules/.pnpm/[email protected]_@[email protected][email protected]_@[email protected][email protected]/node_modules/drizzle-orm/node-postgres/session.cjs:159:18\n    at async NodePgPreparedQuery.queryWithCache (/app/node_modules/.pnpm/[email protected]_@[email protected][email protected]_@[email protected][email protected]/node_modules/drizzle-orm/pg-core/session.cjs:64:16)\n    at async /app/node_modules/.pnpm/[email protected]_@[email protected][email protected]_@[email protected][email protected]/node_modules/drizzle-orm/node-postgres/session.cjs:152:22\n    at async BookRepository.findCards (/app/dist/modules/book/book.repository.js:72:22)\n    at async BookService.executeBooksQuery (/app/dist/modules/book/book.service.js:852:137)"}
bookorbit           | {"level":50,"time":1783008227354,"pid":7,"hostname":"a72f13f989fa","req":{"id":"req-l58","method":"POST","url":"/api/v1/books/query"},"res":{"statusCode":500},"msg":"[HTTP] POST /api/v1/books/query 500 - failed with status code 500"}

bookorbit           | {"level":50,"time":1783008234071,"pid":7,"hostname":"a72f13f989fa","req":{"id":"req-l5s","method":"GET","url":"/api/v1/smart-scopes"},"context":"GlobalExceptionFilter","err":{"type":"DrizzleQueryError","message":"Failed query: select count(*) from \"books\" left join \"book_metadata\" on \"book_metadata\".\"book_id\" = \"books\".\"id\" where ((\"books\".\"library_id\" in ($1, $2, $3) and (SELECT (\"user_book_status\".\"finished_at\" AT TIME ZONE $4)::date FROM \"user_book_status\" WHERE \"user_book_status\".\"book_id\" = \"books\".\"id\" AND \"user_book_status\".\"user_id\" = $5) >= (timezone($6, now())::date - $7)) and \"books\".\"status\" <> $8)\nparams: 3,1,2,America/Chicago,1,America/Chicago,29,processing: operator does not exist: date >= integer","stack":"Error: Failed query: ...\n    at async BookRepository.countWhere (/app/dist/modules/book/book.repository.js:807:29)\n    at async /app/dist/modules/smart-scope/smart-scope.service.js:68:31\n    at async Promise.all (index 0)\ncaused by: error: operator does not exist: date >= integer"}
bookorbit           | {"level":50,"time":1783008234071,"pid":7,"hostname":"a72f13f989fa","req":{"id":"req-l5s","method":"GET","url":"/api/v1/smart-scopes"},"res":{"statusCode":500},"msg":"[HTTP] GET /api/v1/smart-scopes 500 - failed with status code 500"}

Screenshots (optional)

No response

Before submitting

  • I've searched existing issues and this hasn't been reported yet.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingreleasedIssue or PR is included in a released version.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions