What went wrong?
Description
Triggering the author enrichment backfill ("Run for eligible authors" / "Run for all authors" under Settings → Metadata → Authors) returns HTTP 500 and the UI shows a Failed to queue author backfill toast. Nothing is queued.
The server-side error is a RangeError: Maximum call stack size exceeded originating inside drizzle-orm's SQL builder while constructing an INSERT. This appears to be scale-dependent: the library in question has roughly 45,000 eligible authors, and the backfill seems to build a single large query for all of them at once rather than chunking it.
Probable cause (hypothesis)
The stack trace points to deep recursion in drizzle-orm's mergeQueries / buildQueryFromSourceParams while assembling a single INSERT (insert.cjs). This is consistent with the backfill enqueuing one INSERT for all eligible authors at once. At ~45,000 rows the parameter/SQL chunk tree gets deep enough to overflow the V8 call stack.
Chunking the insert into batches (e.g. 500–1000 rows per statement) would likely resolve it. Smaller libraries almost certainly never hit this, which is why it may have gone unnoticed.
Additional context
- Reproducible on demand at this scale; happens with both Run for eligible authors and Run for all authors.
- It is not memory pressure (this is a call-stack overflow, distinct from heap exhaustion); the host has ample free RAM.
Steps to reproduce
- Have a library with a very large number of authors (here, ~45,000 eligible).
- Go to Settings → Metadata → Authors (Author Auto-Fetch).
- Set Update strategy = "Only fill missing data" and at least one eligibility condition (reproduced with "Missing photo" alone, and with "Missing bio" + "Missing photo"). The UI reports ~45,000 eligible authors.
- Click Run for eligible authors (also fails with Run for all authors).
- Backend returns 500; UI shows
Failed to queue author backfill.
Expected vs actual behavior
Expected behavior
The enrichment jobs are queued successfully (presumably in batches) without crashing, regardless of how many authors are eligible.
Actual behavior
POST /api/v1/authors/enrichment/backfill returns 500 after ~3s.
- Backend throws
RangeError: Maximum call stack size exceeded.
- No jobs are queued.
Your setup
- BookOrbit version: v2.0.1
- Image:
ghcr.io/bookorbit/bookorbit:latest
- Database: bundled
pgvector/pgvector:pg16
- Deployment: Docker Compose
- Host OS: Ubuntu 22.04 LTS, Docker CE
- drizzle-orm: 0.45.2
Relevant logs (optional)
{"level":50,"context":"GlobalExceptionFilter","err":{"type":"RangeError","message":"Maximum call stack size exceeded","stack":"RangeError: Maximum call stack size exceeded
at mergeQueries (/app/node_modules/.pnpm/[email protected]_.../node_modules/drizzle-orm/sql/sql.cjs:59:19)
at SQL.buildQueryFromSourceParams (/app/node_modules/.../drizzle-orm/sql/sql.cjs:124:12)
at /app/node_modules/.../drizzle-orm/sql/sql.cjs:103:26
at Object.startActiveSpan (/app/node_modules/.../drizzle-orm/tracing.cjs:31:14)
at SQL.toQuery (/app/node_modules/.../drizzle-orm/sql/sql.cjs:102:34)
at PgDialect.sqlToQuery (/app/node_modules/.../drizzle-orm/pg-core/dialect.cjs:431:17)
at /app/node_modules/.../drizzle-orm/pg-core/query-builders/insert.cjs:190:53
at Object.startActiveSpan (/app/node_modules/.../drizzle-orm/tracing.cjs:31:14)
at QueryPromise._prepare (/app/node_modules/.../drizzle-orm/pg-core/query-builders/insert.cjs:189:34)
at QueryPromise.execute (/app/node_modules/.../drizzle-orm/pg-core/query-builders/insert.cjs:206:34)
at QueryPromise.then (/app/node_modules/.../drizzle-orm/query-promise.cjs:44:17)
at process.processTicksAndRejections (node:internal/process/task_queues:103:5)"}}
[HTTP] POST /api/v1/authors/enrichment/backfill 500 - failed with status code 500 (responseTime: 2999ms)
Screenshots (optional)
No response
Before submitting
What went wrong?
Description
Triggering the author enrichment backfill ("Run for eligible authors" / "Run for all authors" under Settings → Metadata → Authors) returns HTTP 500 and the UI shows a
Failed to queue author backfilltoast. Nothing is queued.The server-side error is a
RangeError: Maximum call stack size exceededoriginating insidedrizzle-orm's SQL builder while constructing anINSERT. This appears to be scale-dependent: the library in question has roughly 45,000 eligible authors, and the backfill seems to build a single large query for all of them at once rather than chunking it.Probable cause (hypothesis)
The stack trace points to deep recursion in drizzle-orm's
mergeQueries/buildQueryFromSourceParamswhile assembling a singleINSERT(insert.cjs). This is consistent with the backfill enqueuing one INSERT for all eligible authors at once. At ~45,000 rows the parameter/SQL chunk tree gets deep enough to overflow the V8 call stack.Chunking the insert into batches (e.g. 500–1000 rows per statement) would likely resolve it. Smaller libraries almost certainly never hit this, which is why it may have gone unnoticed.
Additional context
Steps to reproduce
Failed to queue author backfill.Expected vs actual behavior
Expected behavior
The enrichment jobs are queued successfully (presumably in batches) without crashing, regardless of how many authors are eligible.
Actual behavior
POST /api/v1/authors/enrichment/backfillreturns 500 after ~3s.RangeError: Maximum call stack size exceeded.Your setup
ghcr.io/bookorbit/bookorbit:latestpgvector/pgvector:pg16Relevant logs (optional)
{"level":50,"context":"GlobalExceptionFilter","err":{"type":"RangeError","message":"Maximum call stack size exceeded","stack":"RangeError: Maximum call stack size exceeded at mergeQueries (/app/node_modules/.pnpm/[email protected]_.../node_modules/drizzle-orm/sql/sql.cjs:59:19) at SQL.buildQueryFromSourceParams (/app/node_modules/.../drizzle-orm/sql/sql.cjs:124:12) at /app/node_modules/.../drizzle-orm/sql/sql.cjs:103:26 at Object.startActiveSpan (/app/node_modules/.../drizzle-orm/tracing.cjs:31:14) at SQL.toQuery (/app/node_modules/.../drizzle-orm/sql/sql.cjs:102:34) at PgDialect.sqlToQuery (/app/node_modules/.../drizzle-orm/pg-core/dialect.cjs:431:17) at /app/node_modules/.../drizzle-orm/pg-core/query-builders/insert.cjs:190:53 at Object.startActiveSpan (/app/node_modules/.../drizzle-orm/tracing.cjs:31:14) at QueryPromise._prepare (/app/node_modules/.../drizzle-orm/pg-core/query-builders/insert.cjs:189:34) at QueryPromise.execute (/app/node_modules/.../drizzle-orm/pg-core/query-builders/insert.cjs:206:34) at QueryPromise.then (/app/node_modules/.../drizzle-orm/query-promise.cjs:44:17) at process.processTicksAndRejections (node:internal/process/task_queues:103:5)"}} [HTTP] POST /api/v1/authors/enrichment/backfill 500 - failed with status code 500 (responseTime: 2999ms)Screenshots (optional)
No response
Before submitting