Worker exits at startup (graph unopenable) when a :block/uuid index entry has no entity
Nobody has claimed this yet.
- Dominant language
- No language data
- Stars
- 28
- Forks
- 2
- PR merge metrics
- No merged PRs in 30d
Description
Search first
- I searched and no similar issues were found
What Happened?
One of my DB graphs can no longer be opened at all on recent builds. The worker exits during startup and the graph is unreachable from both the app and the CLI:
Error (server-start-failed): Worker exited before becoming ready; startup cleanup failed:
Worker close failed: Cannot store nil as a value at {:db/id nil, :block/tx-id 536885855}
The same graph opens normally on an older build (b09316a), so nothing about the graph's contents is unreadable in itself.
The cause is ensure-canonical-revisions!, which runs at startup and walks the :block/uuid AVET index, writing :block/tx-id to each entity. This graph has 3 index entries with no entity behind them (out of 1,215). For those, (d/entity db e) is nil, so the code writes {:db/id nil …} and the transaction throws. One stale index entry makes the whole graph unopenable.
Read-only counts from a copy of db.sqlite:
| Count | |
|---|---|
:block/uuid datoms in the AVET index |
1,215 |
entities actually reachable ([:find (count ?e) :where [?e :block/uuid]], older build) |
1,212 |
index entries whose d/entity is nil |
3 |
Each of the three has no rows in any other index: (d/datoms db :eavt e) is empty and (d/datoms db :aevt :block/uuid e) is 0. So they exist only in the AVET index.
How the graph ended up with stale index entries, I don't know — this report is about startup being fatal because of them.
Reproduce the Bug
I can't offer a from-scratch reproduction, since I don't know how the stale entries were created. On a graph that has one:
- Open the graph with a build that includes
fb1047d1f8(e.g.6bf8fe772f), from the app or vialogseq graph info --graph <graph>. - The worker exits during startup and the graph can't be opened. The message above appears in
~/logseq/graphs/<graph>/db-worker-node-<date>.log, after{:db-worker/on-become-master-start …}. - Open the same graph with a build from before that commit (e.g.
b09316a): it opens normally.
To check whether a graph has such entries, on a build that can still open it:
;; datoms in the index vs entities that actually exist
(count (d/datoms db :avet :block/uuid))
(count (filter #(nil? (d/entity db (:e %))) (d/datoms db :avet :block/uuid)))
Expected Behavior
A stale index entry shouldn't make a graph unopenable. ensure-canonical-revisions! could skip datoms whose entity is missing (or use (:e datom) instead of (:db/id entity)), and ideally report or clean up the stale entries rather than failing startup.
Screenshots
Browser, Desktop or Mobile Platform Information
macOS 26.6.2 (25G83), arm64. Desktop app 2.0.1 — local build of 6bf8fe772f (built 2026-09-16), CLI logseq --version → Revision: 6bf8fe7-dirty. Working build for comparison: b09316a. Affected graph: DB graph, schema-version {:major 65 :minor 33}, created about a year ago, local (no RTC graph uuid).
Additional Context
Investigation (at 6bf8fe772f; the same code is on current master)
- Where:
src/main/frontend/worker/db_core.cljs:714-724—ensure-canonical-revisions!:(keep (fn [datom] (let [entity (d/entity db (:e datom))] (when-not (nat-int? (:block/tx-id entity)) {:db/id (:db/id entity) :block/tx-id tx-id}))) (d/datoms db :avet :block/uuid))(:db/id entity)isnilwhen the entity is missing, and the resulting map is transacted. - Introduced in
fb1047d1f8("refactor: data fetch && reactivity", 2026-07-20), which is not inb09316a— matching the observation that the older build opens the graph. - Why it fails (confirmed): a read-only probe over a copy of the graph found 3 AVET entries with no entity, and the tx-id in the error is consistent with the
(inc (:max-tx db))this function uses (my copy of the graph reports536885853, the errors showed…854and…855on successive attempts). - Error reporting differs by build (confirmed):
f7362f0-dirtysurfaced onlyserver-start-timeout-orphanwith the real cause in the worker log;6bf8fe772fsurfaces the message directly. The latter is much easier to diagnose. - 43 real entities in this graph legitimately lack
:block/tx-idand would be backfilled fine; only the 3 phantom index entries break it (a probe counting through the index sees 46, i.e. 43 + 3).
Are you willing to submit a PR? If you know how to fix the bug.
Not planning to, but happy to test a fix or run further read-only probes on the affected graph.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at src/main/frontend/worker/db_core.cljs:714-724, in ensure-canonical-revisions!, and inspect how :block/uuid AVET datoms are converted to entities before the startup transaction. Reproduce with the affected graph or the provided read-only datom/entity counts; done means graphs containing missing entities no longer fail during startup while real entities still receive canonical revisions.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- clojure, sqlite
- Domain
- databases
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100