From 7e596e1e8c6048b69f68c152626277e8c057ae2a Mon Sep 17 00:00:00 2001 From: Lcstyle Date: Wed, 5 Aug 2026 09:05:19 -0400 Subject: [PATCH] fix(api): create_page must store real map properties, not a cljs-bean view logseq.api/create_page converted the caller-supplied properties object with bean/->clj. That returns a lazy cljs-bean Bean view rather than a persistent map, and frontend.handler.page/create! stores it verbatim as the page entity's :block/properties. datascript-transit registers write handlers only for DB, Datom and BTSet, so a Bean is unwritable. From the moment a plugin creates a page with a non-empty properties map, every frontend.db/persist! throws Error: Cannot write $cljs_bean$core$Bean$$ at com.cognitect.transit.impl.writer/marshal ... frontend.db.utils/db->string ... frontend.db/persist! and the graph cache is never written again for the rest of the session. js->clj with :keywordize-keys converts deeply and eagerly, so nested objects and arrays become maps and vectors rather than nested Bean/ArrayVector views. Only the properties argument is changed; opts is destructured immediately and never stored, so it can stay as it is. Empty property maps were unaffected because create! guards with (seq properties), which is why this only reproduced for plugins that pass actual properties. Refs logseq/logseq#8536 --- src/main/logseq/api.cljs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/logseq/api.cljs b/src/main/logseq/api.cljs index 46945d3059..46299e9948 100644 --- a/src/main/logseq/api.cljs +++ b/src/main/logseq/api.cljs @@ -556,7 +556,13 @@ (fn [name ^js properties ^js opts] (some-> (if-let [page (db-model/get-page name)] page - (let [properties (bean/->clj properties) + ;; NOTE: `properties` is stored verbatim as the page entity's + ;; :block/properties (see frontend.handler.page/create!), so it must be a + ;; real persistent map. `bean/->clj` returns a lazy cljs-bean view, which + ;; datascript-transit has no write handler for -- once one is in the DB, + ;; every later `frontend.db/persist!` throws "Cannot write Bean" and the + ;; graph can never be saved again. `js->clj` converts deeply and eagerly. + (let [properties (js->clj properties :keywordize-keys true) {:keys [redirect createFirstBlock format journal]} (bean/->clj opts) name (page-handler/create! name