siyuan-note/siyuan · error · obsidianUserError
read referenced attachment [%s]: %w
Error message
read referenced attachment [%s]: %w
What it means
Wrapped error returned during asset validation in the analysis phase when a referenced (wiki-linked or embedded) attachment file cannot be read. validateObsidianReadableFile tries to open and read one byte from the file and re-validates its metadata; on failure, if the asset is referenced by at least one note, the error is wrapped via newObsidianUserError with i18n detail key 348 and the asset's relative path. Unreferenced unreadable assets are merely warned about, not fatal.
Source
Thrown at kernel/model/import_obsidian.go:541
progress(35, "Analyzing Markdown syntax")
if err = analyzeObsidianDocuments(ctx, ret, progress); err != nil {
return nil, err
}
ret.Analysis.MarkdownCount = countObsidianSourceDocs(ret.Docs)
var assetKeys []string
for key := range ret.Assets {
assetKeys = append(assetKeys, key)
}
sort.Strings(assetKeys)
for _, key := range assetKeys {
if err = ctx.Err(); err != nil {
return nil, err
}
asset := ret.Assets[key]
if err = validateObsidianReadableFile(asset.Source); err != nil {
if ret.ReferencedAssets[key] != nil {
return nil, newObsidianUserError(348, asset.Source.RelPath,
fmt.Errorf("read referenced attachment [%s]: %w", asset.Source.RelPath, err))
}
ret.Analysis.Warnings = append(ret.Analysis.Warnings, asset.Source.RelPath)
continue
}
ret.ImportAssets[key] = asset
ret.Analysis.ImportableAssetCount++
ret.Analysis.ImportableAssetSize += asset.Source.Size
}
ret.Analysis.UnreferencedFileCount = len(ret.ImportAssets) - len(ret.ReferencedAssets)
if ret.Analysis.UnreferencedFileCount < 0 {
ret.Analysis.UnreferencedFileCount = 0
}
progress(100, "Analysis completed")
return ret, nil
}
func validateObsidianVaultRoot(localPath string) (string, error) {
if strings.TrimSpace(localPath) == "" {View on GitHub (pinned to 251596fc0d)
Solutions
- Ensure all referenced attachments are present and readable at the time of analysis; fix or remove broken wiki-link/embed references in the source notes.
- Pause cloud-sync and close Obsidian before analyzing to prevent mid-scan file changes.
- Check the asset path named in the error — restore the file or update the note's link to point at the correct location.
- If the asset is genuinely optional, remove the reference from the note so it falls into the unreferenced (warn-only) path.
Example fix
// before: note references [[attachment.png]] which is missing/unreadable // analysis -> newObsidianUserError(348, relPath, "read referenced attachment [x]: ...") // after: restore the file or remove the reference // either: place attachment.png back in the vault // or: edit the note to remove the broken ![[attachment.png]] embed
Defensive patterns
Strategy: validation
Validate before calling
// Pre-check that referenced attachments are readable
func referencedAssetReadable(absPath string) error {
f, err := os.Open(absPath)
if err != nil { return err }
defer f.Close()
buf := make([]byte, 1)
if _, err := f.Read(buf); err != nil && !errors.Is(err, io.EOF) { return err }
return nil
} Try / catch
if _, err := analyzeVault(ctx, localPath); err != nil {
var ue *obsidianUserError
if errors.As(err, &ue) && strings.Contains(err.Error(), "read referenced attachment") {
return fmt.Errorf("a referenced attachment (%s) could not be read; restore it or fix the link", ue.RelPath)
}
} Prevention
- Ensure all referenced attachments exist and are readable at analysis time.
- Remove or fix broken wiki-link/embed references in source notes.
- Pause sync clients and close Obsidian before analyzing to avoid mid-scan changes.
When it happens
Trigger: During analyzeObsidianVault's asset-collection loop (line 533-543), a ReferencedAssets entry fails validateObsidianReadableFile — the file cannot be opened, read, or its size/mtime no longer matches the scan snapshot. Because at least one note references it, the analysis fails with this wrapped error rather than skipping it.
Common situations: An attachment referenced by a wiki link was deleted or moved between scan and validation; the file is locked or permission-denied on read; the file is on a network path that became unavailable; the file's size/mtime changed mid-analysis (sync client writing); a referenced asset is a broken symlink.
Related errors
- Obsidian Vault is unreadable
- Obsidian Vault path is not a directory
- Obsidian Vault path is unsafe
- Obsidian Vault config directory is missing
- Obsidian Vault has no readable Markdown
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/6522fb9cf1084f56.
Report an issue: GitHub.