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
Thrown by EnsureOnboarding() via Conf.Language(34) which resolves to 'This operation is not supported in read-only mode'. The onboarding flow (creating notebooks/documents for new users) is blocked when the kernel is running in read-only mode or when Conf.Publish.Enable is true (publish mode). This is a hard guard preventing data mutation in restricted deployment modes.
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 251596fc0d)
Solutions
- If onboarding is needed, disable read-only mode (--readonly=false) and ensure Conf.Publish.Enable is false during the initial user setup.
- For publish-mode deployments, dismiss or complete onboarding before enabling publish, or set Conf.Onboarding.NewUser=false in the config.
- In the calling code, check util.ReadOnly and Conf.Publish.Enable before calling EnsureOnboarding() and skip silently or show a different message.
Example fix
// before
onboarding, created, err := model.EnsureOnboarding()
// after
if util.ReadOnly || model.Conf.Publish.Enable {
// Skip onboarding in read-only/publish mode
return
}
onboarding, created, err := model.EnsureOnboarding() Defensive patterns
Strategy: validation
Validate before calling
if util.ReadOnly || Conf.Publish.Enable {
// Skip onboarding; show a static message instead
return nil, false, nil
} Type guard
func canOnboard() bool {
return !util.ReadOnly && !Conf.Publish.Enable
} Prevention
- Check util.ReadOnly and Conf.Publish.Enable before calling EnsureOnboarding().
- For publish-mode deployments, complete or dismiss onboarding before enabling publish.
- Do not expose onboarding-related UI elements in read-only/publish mode.
When it happens
Trigger: Calling EnsureOnboarding() when util.ReadOnly is true or Conf.Publish.Enable is true, and onboarding.NewUser is true and not dismissed and state is not completed. The function returns early with the onboarding clone and this error instead of proceeding to create notebooks.
Common situations: The SiYuan kernel was launched with the --readonly flag for a deployment that only serves published content. The publish feature is enabled, making the instance read-only for viewers. A new user visits a publish-mode instance and the frontend triggers the onboarding check, which correctly refuses.
Related errors
- Please initialize the data repo key first in [Settings - Acc
- This operation is not supported in read-only mode
- unsupported server type: %s
- command is required for stdio server
- start command: %w
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/229e35aff87bf204.
Report an issue: GitHub.