logseq / logseq/db-test

Changing a property's type away from Text leaves its closed values behind, invisible but still enforced

Open
#1,069 2 comments 0 reactions 1 assignee View on GitHub

@tiensonqin is already working on this.

Since Aug 18, 2026.

awaiting-response
Dominant language
No language data
Stars
28
Forks
2
PR merge metrics
No merged PRs in 30d

Description

## Summary

When a property that has **closed values** is changed to type **Node**, the
closed values are not removed. They also stop being visible anywhere in the UI,
because Logseq does not render a closed-value list for Node properties.

The result is a property that looks correctly configured in every screen the UI
offers, but still carries a stale enum in the database. That enum is still
enforced by `validate-db`'s `fix-non-closed-values!` pass, which deletes any
value not in it — and since a Node property's values are node references while
the orphaned enum holds text choices, **every value of that property is
eligible for deletion**.

This issue is about the orphaned state itself. The deletion behaviour is filed
separately as a companion issue, because the two are independently fixable: a
graph that already contains an orphaned enum stays dangerous even if the
deletion pass is corrected, and correcting the type-change path does nothing for
graphs already in this state.

## Version

Logseq DB version, desktop macOS arm64 (build 2287).
`db-worker-node` build-time `2026-07-28T15:15:45Z`, revision `9a11243-dirty`.

## Steps to reproduce

1. Create a property with type **Text** and give it two closed values
(e.g. `raster`, `vector`).
2. Change the property's type to **Node**.
3. Open the property's configuration and look for the closed values.

**Expected:** either the closed values were removed as part of the type change,
or they are shown somewhere so the user knows they still exist — or the type
change is refused while closed values exist, the way a many→one cardinality
change is already refused when data would be lost.

**Actual:** the closed values are still in the database, reachable via
`:block/_closed-value-property`, but appear in no UI surface. There is no way to
discover or delete them from within the app.

## Evidence from a real graph

In the graph where this was found, the affected property was the **only** one of
eleven closed-value properties whose `logseq.property/type` was `node`; the
other ten were all `default`.

Creation timestamps show the ordering: the property was created at
`1783816803975` and its first closed value at `1783816803982` — **seven
milliseconds later**, i.e. created together as a Text property with an enum. The
second closed value followed about three days on. Both long predate the type
being `node`.

There is no UI path to add closed values to a Node property, so they cannot have
been added after the change. The only consistent reading is that the property
was retyped and the closed values were left behind.

## Why it matters

The invisibility is the harmful part. A user inspecting the property sees a
correctly configured Node property. Nothing indicates that a stale enum exists,
that it is still being enforced, or that running "Validate graph" will delete
data because of it.

Verified fix in that graph: deleting the two orphaned closed-value entities
directly made the property behave correctly, because `fix-non-closed-values!`
selects on `:block/_closed-value-property` and skips properties with none. That
repair required going outside the app.

## Suggested fixes

1. **Remove closed values when a property's type changes** to one that does not
support them.
2. Or **refuse the type change while closed values exist**, with a message,
matching the existing precedent for many→one cardinality changes.
3. Failing either, **surface orphaned closed values in the property
configuration UI** so they can be seen and removed.

## Related

Companion issue: logseq/db-test#1068 — `validate-db`'s fix passes silently delete user data
(no notification, `:debug`-only logging, no `:block/updated-at` bump, no UI
refresh). That issue is what turned this configuration inconsistency into
actual lost work.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.