siyuan-note/siyuan · error · obsidianUserError
346
346
Error message
Markdown [%s] changed after analysis: %w
What it means
Per-file markdown drift in revalidateObsidianVault: validateObsidianSourceMetadata(doc.Source) failed because os.Stat now reports a Size or ModTime different from the snapshot taken at scan time. Reported with code 346 ('File [%s] changed after analysis; analyze the Vault again'). This is a finer-grained version of 788/789: even if the file set is stable, content edits are caught by size/mtime.
Source
Thrown at kernel/model/import_obsidian.go:1845
}
if len(vault.Assets) != len(fresh.Assets) {
return newObsidianUserError(349, "", errors.New("the attachment file list changed after analysis"))
}
for key := range vault.Assets {
if fresh.Assets[key] == nil {
return newObsidianUserError(349, "", errors.New("the attachment file list changed after analysis"))
}
}
for _, doc := range vault.Docs {
if doc.Synthetic {
continue
}
if err := ctx.Err(); err != nil {
return err
}
if err := validateObsidianSourceMetadata(doc.Source); err != nil {
return newObsidianUserError(346, doc.Source.RelPath,
fmt.Errorf("Markdown [%s] changed after analysis: %w", doc.Source.RelPath, err))
}
}
for _, asset := range vault.ImportAssets {
if err := ctx.Err(); err != nil {
return err
}
if err := validateObsidianSourceMetadata(asset.Source); err != nil {
return newObsidianUserError(346, asset.Source.RelPath,
fmt.Errorf("attachment [%s] changed after analysis: %w", asset.Source.RelPath, err))
}
}
return nil
}
func validateObsidianSourceMetadata(file *obsidianSourceFile) error {
info, err := os.Stat(file.AbsPath)
if err != nil {
return errView on GitHub (pinned to 251596fc0d)
Solutions
- Stop editing the vault, re-run StartObsidianVaultAnalysis, then immediately import.
- Pause sync/Git for the vault during the analyse→import window.
- If mtime drift is spurious (network FS), copy the vault to a local FS and import from there.
- Disable auto-save or touch-on-open editors for the vault until import completes.
Example fix
// before: edit a note after analysis -> size/mtime differ -> 346 // echo 'new line' >> notes/daily.md (after analysis) // after: finish edits, re-analyse, then import without further edits StartObsidianVaultAnalysis(vault) StartObsidianVaultImport(taskID, nb)
Defensive patterns
Strategy: validation
Validate before calling
// Verify no markdown size/mtime drift since analysis.
func markdownUnchanged(vault string, snap map[string]fileMeta) error { /* compare os.Stat vs snap */ } Type guard
null
Try / catch
null
Prevention
- Stop note-taking and sync during the analyse→import window.
- Use a local copy on a stable FS for network-vault imports.
- Disable auto-save/touch-on-open editors for the vault.
When it happens
Trigger: A markdown file that existed at both times was edited in place: its size and/or mtime changed. Common when the user keeps taking notes in Obsidian after analysis, or a sync client rewrote the file body without adding/removing it.
Common situations: Active note-taking during import; cloud sync pushing content updates; Git pull updating file bodies; an editor's auto-save touching mtime without a real edit; filesystem mtime resolution causing spurious differences on some network FS.
Related errors
- 349
- 345
- attribute view [%s] changed while loading search info
- encrypted notebook is locked, please unlock it first
- OAuth callback was already handled
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/d056ee7eaf9489b9.
Report an issue: GitHub.