siyuan-note/siyuan · error

opened notebook [%s] not found

Error message

opened notebook [%s] not found

What it means

Thrown by mountImportedNotebooks (kernel/api/import.go) during .sy import flows. model.Mount(id) reported success (mounting the imported notebook), but model.Conf.Box(id) then returned nil — the notebook exists on disk yet has no entry in the workspace's notebook configuration. The import aborts rather than returning a half-tracked box.

Source

Thrown at kernel/api/import.go:219

		ret.Msg = "opened notebook [" + createdBoxID + "] not found"
		return
	}
	ret.Data = map[string]any{"type": "notebook", "notebook": box}
	event := util.NewCmdResult("createnotebook", 0, util.PushModeBroadcast)
	event.Data = map[string]any{"box": box, "existed": existed}
	util.PushEvent(event)
}

func mountImportedNotebooks(ids []string) (ret []*model.Box, err error) {
	for _, id := range ids {
		var existed bool
		existed, err = model.Mount(id)
		if nil != err {
			return
		}
		box := model.Conf.Box(id)
		if nil == box {
			return nil, fmt.Errorf("opened notebook [%s] not found", id)
		}
		ret = append(ret, box)
		event := util.NewCmdResult("createnotebook", 0, util.PushModeBroadcast)
		event.Data = map[string]any{"box": box, "existed": existed}
		util.PushEvent(event)
	}
	return
}

func continueImportSY(c *gin.Context) {
	ret := gulu.Ret.NewResult()
	defer c.JSON(http.StatusOK, ret)

	arg, ok := util.JsonArg(c, ret)
	if !ok {
		return
	}
	var token, notebook string

View on GitHub (pinned to afa823b6b4)

Solutions

  1. Retry the import after confirming the notebook's state via /api/notebook/lsNotebooks; if it is mounted but untracked, remove and re-import it
  2. Avoid mutating (closing/removing/reordering) notebooks while an import is in progress
  3. If it recurs consistently, inspect the workspace conf for a stale/partial entry and let the kernel rebuild it on restart, then import again
  4. Import into a fresh notebook id instead of one that other operations are touching
Defensive patterns

Strategy: retry

Validate before calling

const nb = await fetchGet('/api/notebook/lsNotebooks');
const known = nb.data.notebooks.some(n => n.id === importNotebookId);
if (!known) { /* clean state: safe to import */ }
// avoid running imports while notebook open/close/remove operations are active

Type guard

const isTrackedNotebook = (boxId: string, notebooks: { id: string }[]): boolean =>
  notebooks.some(n => n.id === boxId);

Try / catch

try {
  await runSyImport(zipPath);
} catch (e) {
  if (/opened notebook \[.*\] not found/.test(e.message)) {
    await delay(1000);
    const nb = await fetchGet('/api/notebook/lsNotebooks'); // state settles, then retry once
    if (isTrackedNotebook(id, nb.data.notebooks)) await runSyImport(zipPath);
  }
}

Prevention

When it happens

Trigger: Import .sy/.sy.zip flow where the notebook's conf entry is missing or removed concurrently (user closes/removes the notebook in another tab mid-import); conf.json (notebook list) write lost or raced by another operation; importing into a workspace whose configuration file was externally modified or restored mid-run.

Common situations: User reorganizes notebooks while a large import runs; sync engine rewrites conf concurrently; workspace restored from backup during import; two imports or an import plus create-notebook racing on conf writes.

Related errors


AI-assisted analysis of siyuan-note/siyuan@afa823b6b4 (2026-08-18). Data as JSON: /api/errors/c36796dd55195000. Report an issue: GitHub.