Changing a property's type away from Text leaves its closed values behind, invisible but still enforced
@tiensonqin is already working on this.
Since Aug 18, 2026.
- 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
- 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.
Assessment
This issue has not been assessed yet.