siyuan-note/siyuan · warning

An Obsidian Vault import task is already running

Error message

An Obsidian Vault import task is already running

What it means

Returned by StartObsidianVaultAnalysis (i18n key 329) when another Obsidian import task is already active and has progressed past the pre-import states (queued/analyzing/ready). Only one import can run at a time; tasks in creating/writing/indexing/revalidating/staging states cannot be displaced. A task still in a pre-import state is cancelled and replaced silently; this error fires only for tasks that have committed to the import phase.

Source

Thrown at kernel/model/import_obsidian.go:250

	errObsidianVaultUnsafePath      = errors.New("Obsidian Vault path is unsafe")
	errObsidianVaultConfigMissing   = errors.New("Obsidian Vault config directory is missing")
	errObsidianVaultMarkdownMissing = errors.New("Obsidian Vault has no readable Markdown")
	errObsidianSourceChanged        = errors.New("Obsidian source file changed")

	obsidianBlockIDPattern  = regexp.MustCompile(`(?m)(?:^|[ \t])\^([A-Za-z0-9-]+)[ \t]*$`)
	obsidianQuotePattern    = regexp.MustCompile(`^((?:[ \t]*>[ \t]?)+)(.*)$`)
	obsidianListItemPattern = regexp.MustCompile(`^([ \t]*(?:[-+*]|\d+[.)])[ \t]+)(.*)$`)
	obsidianFootnotePattern = regexp.MustCompile(`(?m)\[\^[^\]\r\n]+\]`)
)

func StartObsidianVaultAnalysis(localPath string) (*ObsidianVaultTask, error) {
	var replacedTaskID string
	obsidianTasksMu.Lock()
	if obsidianActive != "" {
		if active := obsidianTasks[obsidianActive]; active != nil && !isObsidianTerminalState(active.State) {
			if !isObsidianPreImportState(active.State) {
				obsidianTasksMu.Unlock()
				return nil, errors.New(Conf.Language(329))
			}
			if active.Cancel != nil {
				active.Cancel()
			}
			replacedTaskID = active.TaskID
			finishObsidianTaskLocked(active, ObsidianTaskStateCancelled, "Import cancelled", "")
		}
	}

	taskID := ast.NewNodeID()
	ctx, cancel := context.WithCancel(context.Background())
	task := &obsidianTask{TaskID: taskID, State: ObsidianTaskStateQueued, Message: "Waiting to analyze", Cancel: cancel}
	obsidianTasks[taskID] = task
	obsidianActive = taskID
	ret := snapshotObsidianTask(task)
	obsidianTasksMu.Unlock()

	if replacedTaskID != "" {

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Wait for the in-progress import task to reach a terminal state (completed/failed/cancelled) before starting a new analysis.
  2. Call POST /api/import/cancelObsidianVaultTask with the active taskID to cancel it, then retry analysis.
  3. Poll GET /api/import/getObsidianVaultTask until state is terminal, then proceed.
  4. Ensure UI controls disable the import button while a task is active.

Example fix

// before: concurrent analysis while import is writing
// POST /api/import/startObsidianVaultAnalysis -> Language(329)

// after: cancel or wait first
task, _ := getObsidianVaultTask(activeTaskID)
if task != nil && !isTerminal(task.State) {
    cancelObsidianVaultTask(activeTaskID)
}
startObsidianVaultAnalysis(newLocalPath)
Defensive patterns

Strategy: validation

Validate before calling

// Check no active import is running before starting analysis
if model.IsObsidianVaultTaskActive() {
    return errors.New("an Obsidian import task is already active")
}

Try / catch

task, err := model.StartObsidianVaultAnalysis(localPath)
if err != nil && err.Error() == Conf.Language(329) {
    // cancel the active task or wait for it, then retry
    return fmt.Errorf("an import is already running (task %s); cancel it first", obsidianActive)
}

Prevention

When it happens

Trigger: POST /api/import/startObsidianVaultAnalysis while a prior task is in a non-terminal, non-pre-import state (isObsidianTerminalState is false and isObsidianPreImportState is false — i.e. state is revalidating, staging, creating, writing, or indexing). The second analysis call is rejected.

Common situations: User clicks 'import' again while a first import is mid-flight in the UI; a stale task ID was not cleaned up and the user retries; a scripted client fires two analysis requests concurrently.

Related errors


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