siyuan-note/siyuan · warning
The Obsidian Vault import task was not found or has expired
Error message
The Obsidian Vault import task was not found or has expired
What it means
Returned by GetObsidianVaultTask (i18n key 330) when no task exists in the in-memory obsidianTasks map for the given taskID. Tasks are deleted after obsidianResultTTL (10 minutes) following a terminal state, and analysis tasks are deleted after obsidianReadyTTL expiry. A taskID that never existed or has been reaped produces this error.
Source
Thrown at kernel/model/import_obsidian.go:280
task := &obsidianTask{TaskID: taskID, State: ObsidianTaskStateQueued, Message: "Waiting to analyze", Cancel: cancel}
obsidianTasks[taskID] = task
obsidianActive = taskID
ret := snapshotObsidianTask(task)
obsidianTasksMu.Unlock()
if replacedTaskID != "" {
removeObsidianTemp(replacedTaskID)
}
go analyzeObsidianVaultTask(ctx, taskID, localPath)
return ret, nil
}
func GetObsidianVaultTask(taskID string) (*ObsidianVaultTask, error) {
obsidianTasksMu.Lock()
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()View on GitHub (pinned to 251596fc0d)
Solutions
- If the task was reaped after completion, start a fresh analysis with startObsidianVaultAnalysis.
- Verify the taskID matches the value returned by the original startObsidianVaultAnalysis or startObsidianVaultImport call.
- Poll more frequently than the 10-minute result TTL to avoid missing the terminal state.
- Handle this error in the UI by resetting to the import-entry screen rather than looping.
Example fix
// before
resp, _ := post("/api/import/getObsidianVaultTask", {taskID: staleID})
// -> { code: -1, msg: "The Obsidian Vault import task was not found or has expired" }
// after: treat not-found/expired as 'start over'
if resp.code !== 0 {
showImportEntryScreen() // user re-selects vault and starts fresh
} Defensive patterns
Strategy: try-catch
Try / catch
task, err := model.GetObsidianVaultTask(taskID)
if err != nil {
if err.Error() == Conf.Language(330) {
// task reaped or unknown — reset to import entry, do not loop
return nil, ErrTaskGone
}
return nil, err
} Prevention
- Poll getObsidianVaultTask at intervals shorter than the 10-minute result TTL.
- Treat a not-found result as 'start over' rather than retrying the same ID.
- Store the taskID returned by startObsidianVaultAnalysis and validate it before polling.
When it happens
Trigger: POST /api/import/getObsidianVaultTask with a taskID that is nil/empty in the map (line 278-280). Occurs when polling a task more than 10 minutes after it finished, polling a fabricated/typo'd ID, or polling after a server restart cleared the in-memory map.
Common situations: The UI retains a stale taskID across a page reload or kernel restart; more than 10 minutes elapsed since the task completed; the taskID was mistyped or truncated in transit; the analysis expired and was reaped.
Related errors
- An Obsidian Vault import task is already running
- The Obsidian Vault import task can no longer be cancelled
- The Obsidian Vault analysis is not ready or has expired
- Obsidian Vault is unreadable: read Vault root: %v
- Obsidian Vault is unreadable
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/82c2092732c30dea.
Report an issue: GitHub.