{"record":{"id":"7c5ef8db631fd506","repo":"siyuan-note/siyuan","slug":"asset-is-not-unused-s","errorCode":null,"errorMessage":"asset is not unused: %s","messagePattern":"asset is not unused: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/assets.go","lineNumber":1121,"sourceCode":"\t\terr = fmt.Errorf(\"asset path resolves outside assets directory: %s\", assetPath)\n\t\treturn\n\t}\n\n\trelativePath = filepath.ToSlash(dataRelativePath)\n\treturn\n}\n\n// ResolveUnusedDataAssetPath 解析 data 相对资源路径，并确认目标当前未被引用。\nfunc ResolveUnusedDataAssetPath(assetPath string) (relativePath, absPath string, err error) {\n\trelativePath, absPath, err = ResolveDataAssetPath(assetPath)\n\tif err != nil {\n\t\treturn\n\t}\n\n\tif unusedAssetsContainPath(relativePath, absPath, UnusedAssets(false)) {\n\t\treturn\n\t}\n\terr = fmt.Errorf(\"asset is not unused: %s\", relativePath)\n\treturn\n}\n\nfunc unusedAssetsContainPath(relativePath, absPath string, items []*UnusedItem) bool {\n\tresolvedPath, _ := ResolveAssetPathWithMissingLeaf(absPath)\n\tfor _, item := range items {\n\t\tif item.AbsPath != \"\" {\n\t\t\tresolvedItemPath, evalErr := ResolveAssetPathWithMissingLeaf(item.AbsPath)\n\t\t\tsamePath, relErr := filepath.Rel(resolvedPath, resolvedItemPath)\n\t\t\tif resolvedPath != \"\" && evalErr == nil && relErr == nil && samePath == \".\" {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\titemPath := filepath.ToSlash(filepath.Clean(filepath.FromSlash(item.Item)))\n\t\tif itemPath == relativePath {\n\t\t\treturn true\n\t\t}","sourceCodeStart":1103,"sourceCodeEnd":1139,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/assets.go#L1103-L1139","documentation":"ResolveUnusedDataAssetPath wraps ResolveDataAssetPath and additionally checks that the target asset appears in the current list of unreferenced assets (UnusedAssets). This error is thrown when the asset exists and resolves fine, but is still referenced by at least one document, so deleting it would break content. It guards RemoveUnusedAsset against destroying in-use files.","triggerScenarios":"Calling ResolveUnusedDataAssetPath (via RemoveUnusedAsset API) with a path whose asset is referenced by any document, or when the unused-assets scan is stale relative to a reference just added.","commonSituations":"A user or automation tries to delete an asset that a recently edited document links to; two concurrent operations where one inserts a reference between the scan and the delete; cache/index lag making the unused list outdated.","solutions":["Run assets/remove-unused-objects (the batch 'remove all unused assets' operation) after re-scanning, so only currently-unused items are removed","Remove or update the document references to the asset first, wait for indexing to complete, then retry the delete","Verify references with an SQL query over blocks for the asset path before deleting","If you are sure the reference is stale, force a re-index of the notebook and retry"],"exampleFix":"// before: delete may hit a referenced asset\nabs, err := model.ResolveUnusedDataAssetPath(p)\n// after: guard and fall back to the scan-based bulk removal\nif err != nil { log.Warnf(\"skip %s: %v\", p, err); return }\nabs, _ := model.ResolveUnusedDataAssetPath(p)","handlingStrategy":"fallback","validationCode":"refs, err := sql.Query(\"SELECT count(1) FROM blocks WHERE content LIKE '%assets/your-file.png%'\")\n// if refs > 0 the asset is in use; skip deletion","typeGuard":null,"tryCatchPattern":"rel, abs, err := model.ResolveUnusedDataAssetPath(p)\nif err != nil {\n\tif strings.Contains(err.Error(), \"is not unused\") {\n\t\t// asset referenced; defer deletion or remove references first\n\t\treturn nil\n\t}\n\treturn err\n}","preventionTips":["Run the full 'remove unused assets' scan instead of deleting individual assets","Re-index notebooks after editing documents so the unused-assets list is fresh","Avoid concurrent document edits and asset deletions in automation scripts"],"tags":["asset-management","referential-integrity"],"backgroundTag":"resource-not-found","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}