siyuan-note/siyuan · error

notebook [%s] was created but could not be opened: %w

Error message

notebook [%s] was created but could not be opened: %w

What it means

Thrown by the `notebook create` subcommand when `model.CreateBox` succeeded (the notebook directory and metadata were written) but the subsequent `model.Mount` failed. This is a partial-state error: the notebook exists on disk but is not opened in the kernel, so it is not indexed or usable until manually opened. The underlying mount error is wrapped via `%w` so `errors.Is`/`errors.As` still see it.

Source

Thrown at kernel/cli/cmd/notebook.go:82

	Use:   "create --name <name>",
	Short: "Create a notebook",
	RunE: func(cmd *cobra.Command, args []string) error {
		name, _ := cmd.Flags().GetString("name")
		if name == "" {
			return fmt.Errorf("--name is required")
		}

		if dryRun {
			fmt.Printf("[dry-run] Would create notebook \"%s\"\n", name)
			return nil
		}

		id, err := model.CreateBox(name)
		if err != nil {
			return err
		}
		if _, err = model.Mount(id); err != nil {
			return fmt.Errorf("notebook [%s] was created but could not be opened: %w", id, err)
		}
		model.AppendPushReloadFiletreeEntry()
		fmt.Println(id)
		return nil
	},
}

func formatNotebookWriteError(boxID string, err error) error {
	if errors.Is(err, model.ErrBoxClosed) {
		return fmt.Errorf("notebook [%s] is closed; run `notebook open --id %s` first", boxID, boxID)
	}
	if errors.Is(err, model.ErrBoxNotFound) {
		return fmt.Errorf("notebook [%s] not found", boxID)
	}
	return err
}

var notebookRemoveCmd = &cobra.Command{

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Open the partially-created notebook explicitly: `siyuan notebook open --id <id from message>`
  2. If open still fails, inspect the wrapped error for the root cause (lock, permissions, disk)
  3. Restart the kernel to release stale locks, then retry `notebook open`
  4. As a last resort, remove the partial notebook (`notebook remove --id <id>`) and recreate it

Example fix

// before
siyuan notebook create --name Research
# -> error: notebook [20240101-xyz] was created but could not be opened: <cause>
// after
siyuan notebook open --id 20240101-xyz
Defensive patterns

Strategy: try-catch

Try / catch

// After create, if Mount fails the notebook exists but is closed.
// Capture the ID from the error and open it explicitly:
id, createErr := model.CreateBox(name)
if createErr != nil { return createErr }
if _, err := model.Mount(id); err != nil {
    // notebook id is now in a partial state; surface it for recovery
    return fmt.Errorf("notebook [%s] created but not opened: %w; run `notebook open --id %s`", id, err, id)
}

Prevention

When it happens

Trigger: `CreateBox` returns a valid new box ID, then `Mount(id)` returns an error — e.g. the index queue fails, a file lock is contended, or the workspace is in a degraded state. The new ID is included in the message so the partial notebook is recoverable.

Common situations: Concurrent workspace access (another process holds a lock); low disk space or permissions issues during indexing; a corrupted workspace that mounts other notebooks but fails on the new one; kernel not fully initialized at create time.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/b71cb3037ae02227. Report an issue: GitHub.