{"record":{"id":"229e35aff87bf204","repo":"siyuan-note/siyuan","slug":"this-operation-is-not-supported-in-read-only-mode","errorCode":null,"errorMessage":"This operation is not supported in read-only mode","messagePattern":"This operation is not supported in read-only mode","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"kernel/model/onboarding.go","lineNumber":109,"sourceCode":"\tonboarding := Conf.Onboarding\n\tif !onboarding.NewUser || onboarding.Dismissed {\n\t\treturn cloneOnboarding(onboarding), false, nil\n\t}\n\n\tboxes, listErr := ListNotebooks()\n\tif listErr != nil {\n\t\treturn cloneOnboarding(onboarding), false, listErr\n\t}\n\tdocumentExists := onboarding.NotebookID != \"\" && onboarding.DocumentID != \"\" && filelock.IsExist(filepath.Join(\n\t\tutil.DataDir, onboarding.NotebookID, onboarding.DocumentID+\".sy\"))\n\tif reconcileOnboarding(onboarding, boxes, documentExists) {\n\t\tConf.Save()\n\t}\n\tif !onboarding.NewUser || onboarding.State == conf.OnboardingCompleted {\n\t\treturn cloneOnboarding(onboarding), false, nil\n\t}\n\tif util.ReadOnly || Conf.Publish.Enable {\n\t\treturn cloneOnboarding(onboarding), false, errors.New(Conf.Language(34))\n\t}\n\n\tif onboarding.NotebookID == \"\" {\n\t\tif len(boxes) > 0 {\n\t\t\tif len(boxes) == 1 && boxes[0].Name == Conf.Language(342) {\n\t\t\t\tonboarding.NotebookID = boxes[0].ID\n\t\t\t\tonboarding.State = conf.OnboardingNotebookCreated\n\t\t\t\tConf.Save()\n\t\t\t} else {\n\t\t\t\tonboarding.State = conf.OnboardingCompleted\n\t\t\t\tonboarding.NewUser = false\n\t\t\t\tConf.Save()\n\t\t\t\treturn cloneOnboarding(onboarding), false, nil\n\t\t\t}\n\t\t}\n\n\t\tif onboarding.NotebookID == \"\" {\n\t\t\tonboarding.NotebookID, err = CreateBox(Conf.Language(342))","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/afa823b6b4e4f183511e0bc0a3be93caa94c7c97/kernel/model/onboarding.go#L91-L127","documentation":"Returned by the onboarding flow (model/onboarding.go) when a new user with an incomplete onboarding state calls an onboarding-advancing API while the kernel runs with util.ReadOnly (launched with --readonly / read-only workspace) or with the publish service enabled (Conf.Publish.Enable). Read-only and publish modes cannot create the onboarding notebook/document, so the operation is refused with Language(34).","triggerScenarios":"Calling the onboarding/status-advancing API on a workspace booted in read-only mode or with publish enabled while onboarding.NewUser is true and State is not conf.OnboardingCompleted. Note the guard only fires for incomplete onboarding: completed or non-new-user sessions return cleanly.","commonSituations":"Publish-service deployments (Conf.Publish.Enable) pointed at a fresh workspace that never completed first-run onboarding; kernels started with --readonly for demo/inspection purposes on a new data dir; Docker/publish images provisioned without running the interactive first-boot flow.","solutions":["Complete onboarding once in a normal read-write, non-publish session on the same workspace, then re-enable read-only/publish mode","Disable publish mode (Conf.Publish.Enable=false) or stop using --readonly so onboarding can create its notebook/document","Provision the workspace by pre-seeding the onboarding notebook/document IDs (onboarding.NotebookID/DocumentID with the .sy present) so reconcileOnboarding marks it complete","If the workspace was never meant to onboard, set the onboarding state to completed via config instead of calling the advancing API"],"exampleFix":"// before\n// kernel started with --readonly, new user calls onboarding API\nmodel.AdvanceOnboarding(...) // -> Language(34)\n\n// after\n// guard the call site\nif util.ReadOnly || Conf.Publish.Enable {\n    http.Error(w, \"onboarding unavailable in read-only/publish mode\", http.StatusConflict)\n    return\n}\nmodel.AdvanceOnboarding(...)","handlingStrategy":"validation","validationCode":"if util.ReadOnly || Conf.Publish.Enable {\n    // skip/queue onboarding-advancing calls; they will fail with Language(34)\n    return nil\n}","typeGuard":"func onboardingAllowed() bool {\n    return !util.ReadOnly && !Conf.Publish.Enable\n}","tryCatchPattern":"if _, _, err := model.GetOnboarding(); err != nil {\n    if err.Error() == Conf.Language(34) {\n        // surface 'complete onboarding in a read-write session' to the operator\n    }\n}","preventionTips":["Complete first-run onboarding before switching a workspace into read-only or publish mode","Provision publish deployments with a pre-onboarded workspace","Boot demo kernels on already-initialized data dirs"],"tags":["siyuan","onboarding","read-only","publish-mode","feature-disabled"],"backgroundTag":"read-only-mode-blocked","analyzedSha":"afa823b6b4e4f183511e0bc0a3be93caa94c7c97","analyzedAt":"2026-08-18T17:04:10.865Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}