project-nomad/admin/app/jobs
Chris Sherwood 74cef75153 fix(RAG): unbreak multi-batch ZIM ingestion (jobId dedupe)
EmbedFileJob.dispatch() uses a deterministic per-file jobId
(sha256(filePath).slice(0,16)) for every batch. The parent batch's
handle() calls EmbedFileJob.dispatch({ batchOffset }) before returning,
so the parent is still in `active` state and locked when the
continuation tries to enqueue. BullMQ silently returns the locked
parent instead of creating a new job — and in newer BullMQ versions
it does so without throwing, so the existing
`catch (error.message.includes('job already exists'))` branch never
fires. After the parent completes, its entry stays in the `completed`
ZSET (held by `removeOnComplete: { count: 50 }`), continuing to trip
jobId dedupe for any subsequent re-dispatch attempts.

Result: every NOMAD install since 2026-02-08 (feat: zim content
embedding) with a multi-batch ZIM (wikipedia, cooking SE, ifixit,
lrnselfreliance, etc.) has only the first 50 articles indexed in
qdrant. The RAG feature has been silently degraded for ~3 months —
the user sees the file appear in their KB, qdrant accumulates ~50
articles' worth of vectors, and pagination quietly halts. No error
surfaces anywhere.

Fix: dispatch() skips the deterministic jobId for continuation batches
(batchOffset > 0), letting BullMQ auto-generate a unique one so each
batch stacks as an independent queue entry. Initial dispatches keep
the deterministic jobId so re-triggering an install (UI re-click,
sync rescan) remains idempotent. The existing 'job already exists'
branch is now gated on !isContinuation, since by construction
continuation batches will never hit dedupe.

Validated on NOMAD8 (RX 6800 / Threadripper 3960X, rc.3 + this patch):
devdocs_en_python (~1,500 chunks across multiple batches) correctly
paginates end-to-end. admin.log shows the expected sequence of
"Dispatched embedding job for file: X (continuation @ offset N)"
followed by "Starting embedding process for: X (batch offset: N)"
for each batch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 10:16:00 -07:00
..
check_service_updates_job.ts feat: support for updating services 2026-03-11 14:08:09 -07:00
check_update_job.ts fix: improve type-safety for KVStore values 2026-03-03 20:51:38 -08:00
download_model_job.ts fix(AI): allow cancelling in-progress model downloads and ensure consistent progress UI (#701) 2026-04-21 14:26:28 -07:00
embed_file_job.ts fix(RAG): unbreak multi-batch ZIM ingestion (jobId dedupe) 2026-05-20 10:16:00 -07:00
run_benchmark_job.ts feat(Docker): container URL resolution util and networking improvs 2026-01-24 15:27:56 -08:00
run_download_job.ts fix(downloads): improved handling for large file downloads and user-initiated cancellation (#632) 2026-04-03 14:26:50 -07:00
run_extract_pmtiles_job.ts feat(Maps): regional map downloads via go-pmtiles extract (#780) 2026-05-20 10:16:00 -07:00