siyuan-note/siyuan · warning
This operation is not supported in read-only mode
Error message
This operation is not supported in read-only mode
What it means
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).
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
Example fix
// before
// kernel started with --readonly, new user calls onboarding API
model.AdvanceOnboarding(...) // -> Language(34)
// after
// guard the call site
if util.ReadOnly || Conf.Publish.Enable {
http.Error(w, "onboarding unavailable in read-only/publish mode", http.StatusConflict)
return
}
model.AdvanceOnboarding(...) Defensive patterns
Strategy: validation
Validate before calling
if util.ReadOnly || Conf.Publish.Enable {
// skip/queue onboarding-advancing calls; they will fail with Language(34)
return nil
} Type guard
func onboardingAllowed() bool {
return !util.ReadOnly && !Conf.Publish.Enable
} Try / catch
if _, _, err := model.GetOnboarding(); err != nil {
if err.Error() == Conf.Language(34) {
// surface 'complete onboarding in a read-write session' to the operator
}
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
AI-assisted analysis of siyuan-note/siyuan@afa823b6b4 (2026-08-18).
Data as JSON: /api/errors/229e35aff87bf204.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/onboarding.go:109
onboarding := Conf.Onboarding
if !onboarding.NewUser || onboarding.Dismissed {
return cloneOnboarding(onboarding), false, nil
}
boxes, listErr := ListNotebooks()
if listErr != nil {
return cloneOnboarding(onboarding), false, listErr
}
documentExists := onboarding.NotebookID != "" && onboarding.DocumentID != "" && filelock.IsExist(filepath.Join(
util.DataDir, onboarding.NotebookID, onboarding.DocumentID+".sy"))
if reconcileOnboarding(onboarding, boxes, documentExists) {
Conf.Save()
}
if !onboarding.NewUser || onboarding.State == conf.OnboardingCompleted {
return cloneOnboarding(onboarding), false, nil
}
if util.ReadOnly || Conf.Publish.Enable {
return cloneOnboarding(onboarding), false, errors.New(Conf.Language(34))
}
if onboarding.NotebookID == "" {
if len(boxes) > 0 {
if len(boxes) == 1 && boxes[0].Name == Conf.Language(342) {
onboarding.NotebookID = boxes[0].ID
onboarding.State = conf.OnboardingNotebookCreated
Conf.Save()
} else {
onboarding.State = conf.OnboardingCompleted
onboarding.NewUser = false
Conf.Save()
return cloneOnboarding(onboarding), false, nil
}
}
if onboarding.NotebookID == "" {
onboarding.NotebookID, err = CreateBox(Conf.Language(342))View on GitHub (pinned to afa823b6b4)