{"record":{"id":"6522fb9cf1084f56","repo":"siyuan-note/siyuan","slug":"read-referenced-attachment-s-w","errorCode":null,"errorMessage":"read referenced attachment [%s]: %w","messagePattern":"read referenced attachment \\[(.+?)\\]: %w","errorType":"exception","errorClass":"obsidianUserError","httpStatus":null,"severity":"error","filePath":"kernel/model/import_obsidian.go","lineNumber":541,"sourceCode":"\tprogress(35, \"Analyzing Markdown syntax\")\n\tif err = analyzeObsidianDocuments(ctx, ret, progress); err != nil {\n\t\treturn nil, err\n\t}\n\tret.Analysis.MarkdownCount = countObsidianSourceDocs(ret.Docs)\n\tvar assetKeys []string\n\tfor key := range ret.Assets {\n\t\tassetKeys = append(assetKeys, key)\n\t}\n\tsort.Strings(assetKeys)\n\tfor _, key := range assetKeys {\n\t\tif err = ctx.Err(); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tasset := ret.Assets[key]\n\t\tif err = validateObsidianReadableFile(asset.Source); err != nil {\n\t\t\tif ret.ReferencedAssets[key] != nil {\n\t\t\t\treturn nil, newObsidianUserError(348, asset.Source.RelPath,\n\t\t\t\t\tfmt.Errorf(\"read referenced attachment [%s]: %w\", asset.Source.RelPath, err))\n\t\t\t}\n\t\t\tret.Analysis.Warnings = append(ret.Analysis.Warnings, asset.Source.RelPath)\n\t\t\tcontinue\n\t\t}\n\t\tret.ImportAssets[key] = asset\n\t\tret.Analysis.ImportableAssetCount++\n\t\tret.Analysis.ImportableAssetSize += asset.Source.Size\n\t}\n\tret.Analysis.UnreferencedFileCount = len(ret.ImportAssets) - len(ret.ReferencedAssets)\n\tif ret.Analysis.UnreferencedFileCount < 0 {\n\t\tret.Analysis.UnreferencedFileCount = 0\n\t}\n\tprogress(100, \"Analysis completed\")\n\treturn ret, nil\n}\n\nfunc validateObsidianVaultRoot(localPath string) (string, error) {\n\tif strings.TrimSpace(localPath) == \"\" {","sourceCodeStart":523,"sourceCodeEnd":559,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/model/import_obsidian.go#L523-L559","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: note references [[attachment.png]] which is missing/unreadable\n// analysis -> newObsidianUserError(348, relPath, \"read referenced attachment [x]: ...\")\n\n// after: restore the file or remove the reference\n// either: place attachment.png back in the vault\n// or:   edit the note to remove the broken ![[attachment.png]] embed","handlingStrategy":"validation","validationCode":"// Pre-check that referenced attachments are readable\nfunc referencedAssetReadable(absPath string) error {\n    f, err := os.Open(absPath)\n    if err != nil { return err }\n    defer f.Close()\n    buf := make([]byte, 1)\n    if _, err := f.Read(buf); err != nil && !errors.Is(err, io.EOF) { return err }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if _, err := analyzeVault(ctx, localPath); err != nil {\n    var ue *obsidianUserError\n    if errors.As(err, &ue) && strings.Contains(err.Error(), \"read referenced attachment\") {\n        return fmt.Errorf(\"a referenced attachment (%s) could not be read; restore it or fix the link\", ue.RelPath)\n    }\n}","preventionTips":["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."],"tags":["obsidian","import","assets","attachments","validation"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}