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
- Open the partially-created notebook explicitly: `siyuan notebook open --id <id from message>`
- If open still fails, inspect the wrapped error for the root cause (lock, permissions, disk)
- Restart the kernel to release stale locks, then retry `notebook open`
- 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
- Parse the box ID out of the error and run `notebook open --id <id>` to recover
- Ensure no other process holds the workspace lock before creating notebooks
- Free disk space and fix permissions to avoid mount/index failures
- On persistent mount failure, `notebook remove --id <id>` the partial box and recreate
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
- notebook [%s] is closed; run `notebook open --id %s` first
- path belongs to encrypted notebook [%s]: %s
- --notebook is required
- --notebook is required
- parent path not found: %s
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/b71cb3037ae02227.
Report an issue: GitHub.