{"record":{"id":"5c81d336610db320","repo":"siyuan-note/siyuan","slug":"walk-notebook-assets-s-failed-w","errorCode":null,"errorMessage":"walk notebook assets [%s] failed: %w","messagePattern":"walk notebook assets \\[(.+?)\\] failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/assets.go","lineNumber":2778,"sourceCode":"\t\t\t\t\t\t\treturn filepath.SkipDir\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn nil\n\t\t\t\t\t}\n\t\t\t\t\trelPath, relErr := assetPathMapKey(assetsDirPath, assetPath, d.IsDir())\n\t\t\t\t\tif relErr != nil {\n\t\t\t\t\t\treturn relErr\n\t\t\t\t\t}\n\t\t\t\t\tassetsAbsPathMap[relPath] = assetPath\n\t\t\t\t\treturn nil\n\t\t\t\t}); nestedWalkErr != nil {\n\t\t\t\t\treturn nestedWalkErr\n\t\t\t\t}\n\t\t\t\treturn filepath.SkipDir\n\t\t\t}\n\t\t\treturn nil\n\t\t})\n\t\tif walkErr != nil {\n\t\t\treturn nil, fmt.Errorf(\"walk notebook assets [%s] failed: %w\", notebookAbsPath, walkErr)\n\t\t}\n\t}\n\n\t// 全局 assets\n\tdataAssetsAbsPath := util.GetDataAssetsAbsPath()\n\twalkErr := filelock.Walk(dataAssetsAbsPath, func(assetPath string, d fs.DirEntry, walkErr error) error {\n\t\tif walkErr != nil {\n\t\t\treturn walkErr\n\t\t}\n\t\tif dataAssetsAbsPath == assetPath {\n\t\t\treturn nil\n\t\t}\n\n\t\tif isSkipFile(d.Name()) {\n\t\t\tif d.IsDir() {\n\t\t\t\treturn filepath.SkipDir\n\t\t\t}\n\t\t\treturn nil","sourceCodeStart":2760,"sourceCodeEnd":2796,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/assets.go#L2760-L2796","documentation":"When listing assets (ListAssetDir or similar scanning), each notebook's assets directory is walked with filelock.Walk. If the walk itself fails (not merely skipping a directory, which returns filepath.SkipDir), the function wraps the cause as \"walk notebook assets [%s] failed\" with the notebook's absolute path, aborting the whole listing.","triggerScenarios":"Calling the asset-listing API while filelock.Walk over a notebook's assets folder returns an error — unreadable directory (permissions), the directory disappearing mid-walk (sync/encryption race), or I/O errors on the underlying filesystem.","commonSituations":"Permission problems after restoring a workspace as another user; encrypted-notebook decryption racing with the walk; the notebook folder being deleted or moved by sync during the scan; filesystem errors (bad sectors, network drives dropping).","solutions":["Check kernel logs for the wrapped underlying walk error and fix the reported notebook directory (permissions, existence).","Ensure the notebook's assets directory exists and is readable by the kernel process.","Retry after sync/encryption passes complete if the directory was being transformed concurrently.","If the notebook directory is corrupt, restore it from sync/backup or remove and re-create the notebook."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const assets = await fetchPost('/api/asset/listAssetDir', {...});\n} catch (e) {\n  if (/walk notebook assets/.test(e.message)) {\n    // underlying cause is in kernel logs; check permissions and retry after sync settles\n    await retryAfterDelay(() => refetchAssets(), 3);\n  }\n}","preventionTips":["Keep notebook directories readable by the kernel process user","Avoid deleting/moving notebooks while asset listing runs","Restore workspaces preserving file ownership and permissions","Check kernel logs for the wrapped walk error to pinpoint the notebook"],"tags":["walk","filesystem","assets","notebook"],"backgroundTag":"file-read-failed","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}