Skip to content

DB: updating a :default property value orphans the previous value block (invisible in UI, accumulates per edit) #1073

Description

@ChipNowacek

Summary

In a DB graph, updating a :default-typed property value creates a new value block and leaves the previous one behind as a child of the owning block, referenced by nothing. Each subsequent edit adds another. The abandoned blocks are not rendered in the UI (property rows only show the current value), so they accumulate invisibly — one dead entity per property edit, indefinitely.

Verified through the CLI. I have not confirmed whether the desktop UI's property editor takes the same path — that's the main open question below, and it decides whether this is a CLI issue or a core one.

Repro (CLI)

# fresh property + class + instance
logseq upsert property --name repro-note --type default --cardinality one
logseq upsert tag --name repro-thing --add-properties repro-note
logseq upsert block --target-page "Repro Page" --content "subject block"
logseq upsert block --id <block> --update-tags repro-thing

# three edits to the same property
logseq upsert block --id <block> --update-properties '{:user.property/repro-note-XXXX "first value"}'
logseq upsert block --id <block> --update-properties '{:user.property/repro-note-XXXX "second value"}'
logseq upsert block --id <block> --update-properties '{:user.property/repro-note-XXXX "third value"}'

Each write returns a different value-block db/id (8192, 8193, 8194).

Actual

;; children of the owning block
[:find ?c ?t :where [?c :block/parent 8191] [?c :block/title ?t]]
=> [[8192 "first value"] [8193 "second value"] [8194 "third value"]]

;; what the property actually points at
[:find ?v ?t :where [8191 :user.property/repro-note-XXXX ?v] [?v :block/title ?t]]
=> [[8194 "third value"]]

Three children, one referenced. logseq/logseq#8192 and logseq/logseq#8193 are unreachable from any property, and don't appear anywhere in the UI.

Expected

Either the value block is mutated in place, or the abandoned one is reclaimed with the property that stopped pointing at it. A block that no property references and that the UI never renders shouldn't persist in the tree.

Also observed: property deletion

Same shape, larger blast radius. In a real graph, deleting a :default-typed property that 26 instances had values for left 26 orphaned value blocks in place — the property was gone, its value blocks were not. Combined with a second retired property, 30 unreferenced blocks across one container, none visible in the UI.

Why it's hard to notice

The UI renders property values as property rows — "this property → its current value". A value block that no property points at has no row to render in, so it is simply never drawn. The only way to find these is a DataScript query against :block/parent. A user editing normally has no signal that anything is accruing.

Open question / scope

My repro drives the CLI (logseq upsert block --update-properties). I have not verified whether the desktop UI's property editor mutates the existing value block or mints a new one. If the UI mutates in place, this is scoped to the CLI's upsert path rather than to the DB layer. Happy to test that if it's useful — I just don't want to overstate what I've actually confirmed.

Environment

  • Logseq CLI — Build time 2026-07-28T15:18:36.673Z, Revision 9a11243
  • DB graph (not file-based)
  • macOS 26.5.2

Suggested query for anyone auditing an existing graph

Unreferenced value blocks under instances of a class, given that class's :default property idents:

[:find ?child ?title
 :where
 [?inst :block/tags ?tag] [?tag :db/ident :user.class/YOUR-CLASS]
 [?child :block/parent ?inst] [?child :block/title ?title]
 (not [?inst :user.property/SOME-DEFAULT-PROP ?child])
 (not [?inst :user.property/ANOTHER-DEFAULT-PROP ?child])]

Node-typed properties don't produce these — they point at existing entities, never at child value blocks — so only :default/:number-style properties need listing in the not clauses.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions