siyuan-note/siyuan · warning
The Obsidian Vault import task can no longer be cancelled
Error message
The Obsidian Vault import task can no longer be cancelled
What it means
Returned by CancelObsidianVaultTask (i18n key 331) when the task exists but is not in a cancellable state. isObsidianCancellableState returns true only for queued, analyzing, ready, revalidating, and staging; once the task reaches creating, writing, or indexing (the committed-write phase), cancellation is refused because partial writes would corrupt the notebook. The endpoint still returns the task snapshot in ret.Data so the caller can see the current state.
Source
Thrown at kernel/model/import_obsidian.go:295
defer obsidianTasksMu.Unlock()
task := obsidianTasks[taskID]
if task == nil {
return nil, errors.New(Conf.Language(330))
}
return snapshotObsidianTask(task), nil
}
func CancelObsidianVaultTask(taskID string) (*ObsidianVaultTask, error) {
obsidianTasksMu.Lock()
task := obsidianTasks[taskID]
if task == nil {
obsidianTasksMu.Unlock()
return nil, errors.New(Conf.Language(330))
}
if !isObsidianCancellableState(task.State) {
ret := snapshotObsidianTask(task)
obsidianTasksMu.Unlock()
return ret, errors.New(Conf.Language(331))
}
if task.Cancel != nil {
task.Cancel()
}
finishObsidianTaskLocked(task, ObsidianTaskStateCancelled, "Import cancelled", "")
ret := snapshotObsidianTask(task)
obsidianTasksMu.Unlock()
removeObsidianTemp(taskID)
return ret, nil
}
func StartObsidianVaultImport(taskID, notebookName string) (*ObsidianVaultTask, error) {
obsidianTasksMu.Lock()
task := obsidianTasks[taskID]
if task == nil || task.State != ObsidianTaskStateReady || task.Context == nil {
obsidianTasksMu.Unlock()
return nil, errors.New(Conf.Language(332))
}View on GitHub (pinned to 251596fc0d)
Solutions
- Wait for the write/index phase to complete — the notebook will be fully written and can be deleted afterward if unwanted.
- Cancel earlier: issue cancel during analyzing, ready, revalidating, or staging, before the committed-write phase begins.
- If the resulting notebook is unwanted, delete it via the notebook management API after the task completes.
- Disable the cancel control in the UI once the task enters a non-cancellable state.
Example fix
// before: cancelling during 'writing' state
post("/api/import/cancelObsidianVaultTask", {taskID})
// -> { code: -1, msg: "... can no longer be cancelled", data: {state:"writing"} }
// after: wait for completion, then remove the notebook if not wanted
waitForTerminal(taskID)
if task.result && task.result.notebookID {
removeNotebook(task.result.notebookID)
} Defensive patterns
Strategy: type-guard
Validate before calling
// Check the task state is cancellable before issuing cancel
func isCancellableState(state string) bool {
switch state {
case "queued", "analyzing", "ready", "revalidating", "staging":
return true
}
return false
} Type guard
func isCancellable(task *ObsidianVaultTask) bool {
if task == nil { return false }
switch task.State {
case "queued", "analyzing", "ready", "revalidating", "staging":
return true
}
return false
} Try / catch
task, err := model.CancelObsidianVaultTask(taskID)
if err != nil && err.Error() == Conf.Language(331) {
// task is past staging — cannot cancel; wait for completion
return fmt.Errorf("import is past the cancellation point (state: %s); wait for completion", task.State)
} Prevention
- Cancel only during queued/analyzing/ready/revalidating/staging states.
- Disable the cancel button once the task enters creating/writing/indexing.
- If the notebook is unwanted, delete it after the task completes.
When it happens
Trigger: POST /api/import/cancelObsidianVaultTask when task.State is creating, writing, or indexing (line 292-295). The task is past the staging point and is actively writing documents to disk.
Common situations: User clicks cancel after the import has begun writing notes to the notebook; a long import is in the indexing phase and the user tries to abort; the UI cancel button was not disabled when the task transitioned to writing.
Related errors
- An Obsidian Vault import task is already running
- The Obsidian Vault import task was not found or has expired
- The Obsidian Vault analysis is not ready or has expired
- Obsidian Vault is unreadable
- Obsidian Vault path is not a directory
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/50b5a643760c1da4.
Report an issue: GitHub.