DB: HTTP API property writes land in :plugin.property._test_plugin/*, but docs specify :plugin.property._api
Nobody has claimed this yet.
- Dominant language
- No language data
- Stars
- 28
- Forks
- 2
- PR merge metrics
- No merged PRs in 30d
Description
## Summary
`db-version-changes.md` states that properties created through the plugin API are namespaced to `:plugin.property._api`:
> All property related calls like `upsertBlockProperty` work with DB graphs. Property values can now be numbers and booleans. Properties are namespaced to `:plugin.property._api`
In practice, properties created through the HTTP API land in `:plugin.property._test_plugin/*`. The string `_api` does not appear anywhere in the repository.
## Cause
`src/main/logseq/api/block.cljs:28`:
```clojure
(defn get-sanitized-plugin-id
[^js plugin]
(or
(when (some-> js/window.LSPlugin (.-PluginLocal))
(some->> plugin (.-id) sanitize-user-property-name))
"_test_plugin"))
```
When there is no `PluginLocal` — the case for HTTP API callers, which are not loaded plugins — this falls back to the literal `"_test_plugin"`. That fallback is on a production path, not a test-only one: `resolve-property-prefix-for-db` uses its result to build the property namespace.
Outside this function, `_test_plugin` appears only in test files (`deps/outliner/test/logseq/outliner/op_test.cljs`, `clj-e2e/test/logseq/e2e/plugins_basic_test.clj`, and two others), which is what makes the name read as a fixture rather than a default.
## Reproduction
1. Open a DB graph in the desktop app and enable the HTTP API server.
2. Call `upsertBlockProperty` with a property name that is not yet defined, e.g. key `nsprobe`, value `probe`.
3. Query the resulting property entity:
```clojure
[:find ?ident ?type
:where
[?p :block/title "nsprobe"]
[?p :db/ident ?ident]
[?p :logseq.property/type ?type]]
```
Actual: `[":plugin.property._test_plugin/nsprobe" "default"]`
Expected per docs: `:plugin.property._api/nsprobe`
## Why it matters
Properties written through the HTTP API are permanently identified by an ident that reads as a test fixture. Idents are the stable identity for properties across graphs — they survive export and import — so this name travels with the data. If the fallback is later corrected to match the documentation, existing idents would need a migration.
## Environment
- Source verified at `master` (`abdc94bf`)
- Reproduced on a desktop build from `9a11243`, DB graph, 2026-08-14
## Possible resolutions
Either change the fallback constant to `_api` (with a migration path for data already written), or update `db-version-changes.md` to document `_test_plugin` as the actual namespace. Implementation and documentation currently disagree in either direction.
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 in src/main/logseq/api/block.cljs at get-sanitized-plugin-id and trace how resolve-property-prefix-for-db builds the property namespace. Compare that behavior with db-version-changes.md and the listed tests, then determine the appropriate implementation or documentation change and account for existing _test_plugin idents in the completion criteria.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- clojure
- Domain
- api, database
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100