siyuan-note/siyuan · warning
Conf.Language(329)
Error message
Conf.Language(329)
What it means
Only one Obsidian Vault import task may run at a time. `ImportObsidianVault` checks `obsidianActive`; if another task is active and already past its pre-import phase (i.e. actually importing), it returns the localized message 'An Obsidian Vault import task is already running' (Conf.Language(329)). This serializes the heavyweight vault conversion.
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 8641553a1f)
Solutions
- Poll `GetObsidianVaultTask(activeTaskID)` and wait until the running task reaches a terminal state (finished/cancelled/failed) before starting a new import
- Call `CancelObsidianVaultTask(taskID)` on the active task, then start the new import
- Avoid duplicate submissions in the UI (disable the button while a task is running)
- If a task appears permanently stuck, restart the kernel to clear the in-memory task registry
Example fix
// before
startImport() // second call -> Conf.Language(329)
// after
task, err := GetObsidianVaultTask(activeTaskID)
if err == nil && !isObsidianTerminalState(task.State) {
CancelObsidianVaultTask(activeTaskID) // wait for cancellation
}
startImport() Defensive patterns
Strategy: try-catch
Try / catch
try {
const task = await importObsidianVault(p)
} catch (e) {
if (e.code === 329) {
await waitForTerminalState(activeTaskID) // poll GetObsidianVaultTask
await importObsidianVault(p) // retry once the active task finished/cancelled
}
} Prevention
- Track the active task ID and poll its state before offering the import action
- Disable the import button in the UI while a task is in a non-terminal state
- Cancel the running task explicitly before starting a new one
- Never launch imports concurrently from scripts or multiple clients
When it happens
Trigger: Calling the Obsidian import API while another import task is in a non-terminal, non-pre-import state — e.g. double-clicking the import button, or a plugin/script starting a second import before the first finishes or is cancelled.
Common situations: User retries impatiently during a long vault conversion; two clients (desktop + API call) start imports concurrently; a previous task is hung in the importing state and blocks new ones.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- 350
- Obsidian Vault is unreadable
- Obsidian Vault path is not a directory
- Obsidian Vault config directory is missing
- Obsidian Vault has no readable Markdown
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/ef0c0c814404ad19.
Report an issue: GitHub.